Repo // Concatenate all UpdateAPI contents into one file.

This commit is contained in:
ShikiSuen 2022-09-08 15:56:29 +08:00
parent 45ef33c645
commit 1cbcb446ee
5 changed files with 127 additions and 119 deletions

View File

@ -10,39 +10,8 @@
import Cocoa import Cocoa
struct VersionUpdateReport {
var siteUrl: URL?
var currentShortVersion: String = ""
var currentVersion: String = ""
var remoteShortVersion: String = ""
var remoteVersion: String = ""
var versionDescription: String = ""
}
enum VersionUpdateApiResult {
case shouldUpdate(report: VersionUpdateReport)
case noNeedToUpdate
case ignored
}
enum VersionUpdateApiError: Error, LocalizedError {
case connectionError(message: String)
var errorDescription: String? {
switch self {
case .connectionError(let message):
return String(
format: NSLocalizedString(
"There may be no internet connection or the server failed to respond.\n\nError message: %@",
comment: ""
), message
)
}
}
}
enum VersionUpdateApi { enum VersionUpdateApi {
static let kCheckUpdateAutomatically = "CheckUpdateAutomatically" static let kCheckUpdateAutomatically = UserDef.kCheckUpdateAutomatically.rawValue
static let kNextUpdateCheckDateKey = "NextUpdateCheckDate" static let kNextUpdateCheckDateKey = "NextUpdateCheckDate"
static let kUpdateInfoEndpointKey = "UpdateInfoEndpoint" static let kUpdateInfoEndpointKey = "UpdateInfoEndpoint"
static let kUpdateInfoSiteKey = "UpdateInfoSite" static let kUpdateInfoSiteKey = "UpdateInfoSite"
@ -161,4 +130,118 @@ enum VersionUpdateApi {
task.resume() task.resume()
return task return task
} }
private static var checkTask: URLSessionTask?
static func checkForUpdate(forced: Bool = false) {
if checkTask != nil {
// busy
return
}
// time for update?
if !forced {
if !mgrPrefs.checkUpdateAutomatically {
return
}
let now = Date()
let date = UserDefaults.standard.object(forKey: VersionUpdateApi.kNextUpdateCheckDateKey) as? Date ?? now
if now.compare(date) == .orderedAscending {
return
}
}
let nextUpdateDate = Date(timeInterval: VersionUpdateApi.kNextCheckInterval, since: Date())
UserDefaults.standard.set(nextUpdateDate, forKey: VersionUpdateApi.kNextUpdateCheckDateKey)
checkTask = VersionUpdateApi.check(forced: forced) { [self] result in
defer {
checkTask = nil
}
switch result {
case .success(let apiResult):
switch apiResult {
case .shouldUpdate(let report):
let content = String(
format: NSLocalizedString(
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@",
comment: ""
),
report.currentShortVersion,
report.currentVersion,
report.remoteShortVersion,
report.remoteVersion,
report.versionDescription
)
IME.prtDebugIntel("vChewingDebug: \(content)")
let alert = NSAlert()
alert.messageText = NSLocalizedString("New Version Available", comment: "")
alert.informativeText = content
alert.addButton(withTitle: NSLocalizedString("Visit Website", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Not Now", comment: ""))
NSApp.setActivationPolicy(.accessory)
let result = alert.runModal()
if result == NSApplication.ModalResponse.alertFirstButtonReturn {
if let siteURL = report.siteUrl {
NSWorkspace.shared.open(siteURL)
}
}
case .noNeedToUpdate, .ignored:
break
}
case .failure(let error):
switch error {
case VersionUpdateApiError.connectionError(let message):
let title = NSLocalizedString("Update Check Failed", comment: "")
let content = String(
format: NSLocalizedString(
"There may be no internet connection or the server failed to respond.\n\nError message: %@",
comment: ""
), message
)
let buttonTitle = NSLocalizedString("Dismiss", comment: "")
IME.prtDebugIntel("vChewingDebug: \(content)")
let alert = NSAlert()
alert.messageText = title
alert.informativeText = content
alert.addButton(withTitle: buttonTitle)
alert.runModal()
NSApp.setActivationPolicy(.accessory)
default:
break
}
}
}
}
struct VersionUpdateReport {
var siteUrl: URL?
var currentShortVersion: String = ""
var currentVersion: String = ""
var remoteShortVersion: String = ""
var remoteVersion: String = ""
var versionDescription: String = ""
}
enum VersionUpdateApiResult {
case shouldUpdate(report: VersionUpdateReport)
case noNeedToUpdate
case ignored
}
enum VersionUpdateApiError: Error, LocalizedError {
case connectionError(message: String)
var errorDescription: String? {
switch self {
case .connectionError(let message):
return String(
format: NSLocalizedString(
"There may be no internet connection or the server failed to respond.\n\nError message: %@",
comment: ""
), message
)
}
}
}
} }

View File

@ -27,7 +27,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
@IBOutlet var window: NSWindow? @IBOutlet var window: NSWindow?
private var ctlPrefWindowInstance: ctlPrefWindow? private var ctlPrefWindowInstance: ctlPrefWindow?
private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window
private var checkTask: URLSessionTask?
public lazy var folderMonitor = FolderMonitor( public lazy var folderMonitor = FolderMonitor(
url: URL(fileURLWithPath: mgrLangModel.dataFolderPath(isDefaultFolder: false)) url: URL(fileURLWithPath: mgrLangModel.dataFolderPath(isDefaultFolder: false))
) )
@ -66,7 +65,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
// 使 // 使
if mgrPrefs.checkUpdateAutomatically { if mgrPrefs.checkUpdateAutomatically {
checkForUpdate() VersionUpdateApi.checkForUpdate()
} }
} }
@ -103,88 +102,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
NSApp.setActivationPolicy(.accessory) NSApp.setActivationPolicy(.accessory)
} }
func checkForUpdate(forced: Bool = false) {
if checkTask != nil {
// busy
return
}
// time for update?
if !forced {
if !mgrPrefs.checkUpdateAutomatically {
return
}
let now = Date()
let date = UserDefaults.standard.object(forKey: VersionUpdateApi.kNextUpdateCheckDateKey) as? Date ?? now
if now.compare(date) == .orderedAscending {
return
}
}
let nextUpdateDate = Date(timeInterval: VersionUpdateApi.kNextCheckInterval, since: Date())
UserDefaults.standard.set(nextUpdateDate, forKey: VersionUpdateApi.kNextUpdateCheckDateKey)
checkTask = VersionUpdateApi.check(forced: forced) { [self] result in
defer {
checkTask = nil
}
switch result {
case .success(let apiResult):
switch apiResult {
case .shouldUpdate(let report):
let content = String(
format: NSLocalizedString(
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@",
comment: ""
),
report.currentShortVersion,
report.currentVersion,
report.remoteShortVersion,
report.remoteVersion,
report.versionDescription
)
IME.prtDebugIntel("vChewingDebug: \(content)")
let alert = NSAlert()
alert.messageText = NSLocalizedString("New Version Available", comment: "")
alert.informativeText = content
alert.addButton(withTitle: NSLocalizedString("Visit Website", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Not Now", comment: ""))
let result = alert.runModal()
if result == NSApplication.ModalResponse.alertFirstButtonReturn {
if let siteURL = report.siteUrl {
NSWorkspace.shared.open(siteURL)
}
}
NSApp.setActivationPolicy(.accessory)
case .noNeedToUpdate, .ignored:
break
}
case .failure(let error):
switch error {
case VersionUpdateApiError.connectionError(let message):
let title = NSLocalizedString("Update Check Failed", comment: "")
let content = String(
format: NSLocalizedString(
"There may be no internet connection or the server failed to respond.\n\nError message: %@",
comment: ""
), message
)
let buttonTitle = NSLocalizedString("Dismiss", comment: "")
IME.prtDebugIntel("vChewingDebug: \(content)")
let alert = NSAlert()
alert.messageText = title
alert.informativeText = content
alert.addButton(withTitle: buttonTitle)
alert.runModal()
NSApp.setActivationPolicy(.accessory)
default:
break
}
}
}
}
func selfUninstall() { func selfUninstall() {
currentAlertType = "Uninstall" currentAlertType = "Uninstall"
let content = String( let content = String(

View File

@ -135,7 +135,7 @@ class ctlInputMethod: IMKInputController {
setKeyLayout() setKeyLayout()
handle(state: IMEState.ofEmpty()) handle(state: IMEState.ofEmpty())
} // } //
(NSApp.delegate as? AppDelegate)?.checkForUpdate() VersionUpdateApi.checkForUpdate()
} }
/// ///

View File

@ -308,7 +308,7 @@ extension ctlInputMethod {
} }
@objc func checkForUpdate(_: Any?) { @objc func checkForUpdate(_: Any?) {
(NSApp.delegate as? AppDelegate)?.checkForUpdate(forced: true) VersionUpdateApi.checkForUpdate(forced: true)
} }
@objc func openUserDataFolder(_: Any?) { @objc func openUserDataFolder(_: Any?) {

View File

@ -423,6 +423,14 @@
path = FolderMonitor; path = FolderMonitor;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
5B16B84D28C9D6BF00ABA692 /* OVUpdateAPI */ = {
isa = PBXGroup;
children = (
5BDC1CF927FDF1310052C2B9 /* apiUpdate.swift */,
);
path = OVUpdateAPI;
sourceTree = "<group>";
};
5B18BA7527C7BF6D0056EB19 /* MiscRootFiles */ = { 5B18BA7527C7BF6D0056EB19 /* MiscRootFiles */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -488,6 +496,7 @@
5B84579B2871AD2200C93B01 /* HotenkaChineseConverter */, 5B84579B2871AD2200C93B01 /* HotenkaChineseConverter */,
5B949BD72816DC4400D87B5D /* LineReader */, 5B949BD72816DC4400D87B5D /* LineReader */,
5B5F8AEC28C86AB3007C11F1 /* NSAttributedTextView */, 5B5F8AEC28C86AB3007C11F1 /* NSAttributedTextView */,
5B16B84D28C9D6BF00ABA692 /* OVUpdateAPI */,
5BA58644289BCFAC0077D02F /* Qwertyyb */, 5BA58644289BCFAC0077D02F /* Qwertyyb */,
5B20430528BEE2F300BFC6FD /* Sandbox */, 5B20430528BEE2F300BFC6FD /* Sandbox */,
5BA9FCEA27FED652002DE248 /* SindreSorhus */, 5BA9FCEA27FED652002DE248 /* SindreSorhus */,
@ -530,7 +539,6 @@
5B62A32227AE756300A19448 /* IMEModules */ = { 5B62A32227AE756300A19448 /* IMEModules */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
5BDC1CF927FDF1310052C2B9 /* apiUpdate.swift */,
5B5E535127EF261400C6AA1E /* IME.swift */, 5B5E535127EF261400C6AA1E /* IME.swift */,
5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */, 5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */,
5B62A33527AE795800A19448 /* mgrPrefs.swift */, 5B62A33527AE795800A19448 /* mgrPrefs.swift */,