mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-10 02:08:38 +09:00
Dactyloidae iOS initial commit
This commit is contained in:
parent
daa6179d22
commit
7154a0497e
2123 changed files with 197052 additions and 0 deletions
|
|
@ -0,0 +1,162 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import Foundation
|
||||
import Shared
|
||||
|
||||
public struct ClipboardBarToastUX {
|
||||
static let ToastDelay = DispatchTimeInterval.milliseconds(4000)
|
||||
}
|
||||
|
||||
protocol ClipboardBarDisplayHandlerDelegate: class {
|
||||
func shouldDisplay(clipboardBar bar: ButtonToast)
|
||||
}
|
||||
|
||||
class ClipboardBarDisplayHandler: NSObject, URLChangeDelegate {
|
||||
weak var delegate: (ClipboardBarDisplayHandlerDelegate & SettingsDelegate)?
|
||||
weak var settingsDelegate: SettingsDelegate?
|
||||
weak var tabManager: TabManager?
|
||||
private var sessionStarted = true
|
||||
private var sessionRestored = false
|
||||
private var firstTabLoaded = false
|
||||
private var prefs: Prefs
|
||||
private var lastDisplayedURL: String?
|
||||
private weak var firstTab: Tab?
|
||||
var clipboardToast: ButtonToast?
|
||||
|
||||
init(prefs: Prefs, tabManager: TabManager) {
|
||||
self.prefs = prefs
|
||||
self.tabManager = tabManager
|
||||
|
||||
super.init()
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(SELUIPasteboardChanged), name: NSNotification.Name.UIPasteboardChanged, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(SELAppWillEnterForegroundNotification), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(SELDidRestoreSession), name: NotificationDidRestoreSession, object: nil)
|
||||
}
|
||||
|
||||
@objc private func SELUIPasteboardChanged() {
|
||||
// UIPasteboardChanged gets triggered when calling UIPasteboard.general.
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIPasteboardChanged, object: nil)
|
||||
|
||||
UIPasteboard.general.asyncURL().uponQueue(.main) { res in
|
||||
defer {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.SELUIPasteboardChanged), name: NSNotification.Name.UIPasteboardChanged, object: nil)
|
||||
}
|
||||
|
||||
guard let copiedURL: URL? = res.successValue,
|
||||
let url = copiedURL else {
|
||||
return
|
||||
}
|
||||
self.lastDisplayedURL = url.absoluteString
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func SELAppWillEnterForegroundNotification() {
|
||||
sessionStarted = true
|
||||
checkIfShouldDisplayBar()
|
||||
}
|
||||
|
||||
private func observeURLForFirstTab(firstTab: Tab) {
|
||||
if firstTab.webView == nil {
|
||||
// Nothing to do; bail out.
|
||||
firstTabLoaded = true
|
||||
return
|
||||
}
|
||||
self.firstTab = firstTab
|
||||
firstTab.observeURLChanges(delegate: self)
|
||||
}
|
||||
|
||||
@objc private func SELDidRestoreSession() {
|
||||
DispatchQueue.main.sync {
|
||||
if let tabManager = self.tabManager,
|
||||
let firstTab = tabManager.selectedTab {
|
||||
self.observeURLForFirstTab(firstTab: firstTab)
|
||||
} else {
|
||||
firstTabLoaded = true
|
||||
}
|
||||
|
||||
NotificationCenter.default.removeObserver(self, name: NotificationDidRestoreSession, object: nil)
|
||||
|
||||
sessionRestored = true
|
||||
checkIfShouldDisplayBar()
|
||||
}
|
||||
}
|
||||
|
||||
func tab(_ tab: Tab, urlDidChangeTo url: URL) {
|
||||
// Ugly hack to ensure we wait until we're finished restoring the session on the first tab
|
||||
// before checking if we should display the clipboard bar.
|
||||
guard sessionRestored,
|
||||
!url.absoluteString.startsWith("\(WebServer.sharedInstance.base)/about/sessionrestore?history=") else {
|
||||
return
|
||||
}
|
||||
|
||||
tab.removeURLChangeObserver(delegate: self)
|
||||
firstTabLoaded = true
|
||||
checkIfShouldDisplayBar()
|
||||
}
|
||||
|
||||
private func shouldDisplayBar(_ copiedURL: String) -> Bool {
|
||||
if !sessionStarted ||
|
||||
!sessionRestored ||
|
||||
!firstTabLoaded ||
|
||||
isClipboardURLAlreadyDisplayed(copiedURL) ||
|
||||
self.prefs.intForKey(IntroViewControllerSeenProfileKey) == nil {
|
||||
return false
|
||||
}
|
||||
sessionStarted = false
|
||||
return true
|
||||
}
|
||||
|
||||
// If we already displayed this URL on the previous session, or in an already open
|
||||
// tab, we shouldn't display it again
|
||||
private func isClipboardURLAlreadyDisplayed(_ clipboardURL: String) -> Bool {
|
||||
if lastDisplayedURL == clipboardURL {
|
||||
return true
|
||||
}
|
||||
|
||||
if let url = URL(string: clipboardURL),
|
||||
let _ = tabManager?.getTabFor(url) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkIfShouldDisplayBar() {
|
||||
guard self.prefs.boolForKey("showClipboardBar") ?? false else {
|
||||
// There's no point in doing any of this work unless the
|
||||
// user has asked for it in settings.
|
||||
return
|
||||
}
|
||||
UIPasteboard.general.asyncURL().uponQueue(.main) { res in
|
||||
guard let copiedURL: URL? = res.successValue,
|
||||
let url = copiedURL else {
|
||||
return
|
||||
}
|
||||
|
||||
let absoluteString = url.absoluteString
|
||||
|
||||
guard self.shouldDisplayBar(absoluteString) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.lastDisplayedURL = absoluteString
|
||||
|
||||
self.clipboardToast =
|
||||
ButtonToast(
|
||||
labelText: Strings.GoToCopiedLink,
|
||||
descriptionText: url.absoluteDisplayString,
|
||||
buttonText: Strings.GoButtonTittle,
|
||||
completion: { buttonPressed in
|
||||
if buttonPressed {
|
||||
self.delegate?.settingsOpenURLInNewTab(url)
|
||||
}
|
||||
})
|
||||
|
||||
if let toast = self.clipboardToast {
|
||||
self.delegate?.shouldDisplay(clipboardBar: toast)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue