Skip to content

Commit

Permalink
Support manually install plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
eagleoflqj committed Jan 2, 2025
1 parent 52fa22f commit 0d53c41
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 15 deletions.
Binary file modified assets/zh-Hans.lproj/Localizable.strings
Binary file not shown.
20 changes: 9 additions & 11 deletions src/config/installer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ let mainDebugFileName = "Fcitx5-\(arch)-debug.tar.bz2"
let pluginBaseAddress =
"https://github.com/fcitx-contrib/fcitx5-plugins/releases/download/macos/"

private func getFileName(_ plugin: String, native: Bool) -> String {
func getPluginFileName(_ plugin: String, native: Bool) -> String {
return native ? "\(plugin)-\(arch).tar.bz2" : "\(plugin)-any.tar.bz2"
}

private func getAddress(_ plugin: String, native: Bool) -> String {
return pluginBaseAddress + getFileName(plugin, native: native)
return pluginBaseAddress + getPluginFileName(plugin, native: native)
}

private func getCacheURL(_ plugin: String, native: Bool) -> URL {
let fileName = getFileName(plugin, native: native)
func getCacheURL(_ plugin: String, native: Bool) -> URL {
let fileName = getPluginFileName(plugin, native: native)
return cacheDir.appendingPathComponent(fileName)
}

Expand All @@ -31,14 +31,13 @@ func getFilesFromDescriptor(_ descriptor: URL) -> [String] {
return json["files"].arrayValue.map { $0.stringValue }
}

private func extractPlugin(_ plugin: String, native: Bool) -> Bool {
func extractPlugin(_ plugin: String, native: Bool) -> Bool {
let descriptor = getPluginDescriptor(plugin)
let oldFiles = getFilesFromDescriptor(descriptor)

mkdirP(libraryDir.localPath())
let url = getCacheURL(plugin, native: native)
let path = url.localPath()
let ret = exec("/usr/bin/tar", ["-xjf", path, "-C", libraryDir.localPath()])
let ret = exec("/usr/bin/tar", ["-xjf", url.localPath(), "-C", libraryDir.localPath()])
let _ = removeFile(url)

if ret {
Expand All @@ -47,8 +46,7 @@ private func extractPlugin(_ plugin: String, native: Bool) -> Bool {
if removedFiles.count > 0 {
FCITX_INFO("Removing \(removedFiles) which are no longer needed")
for file in removedFiles {
let path = libraryDir.appendingPathComponent(file)
let _ = removeFile(path)
let _ = removeFile(libraryDir.appendingPathComponent(file))
}
}
}
Expand Down Expand Up @@ -83,7 +81,7 @@ class Updater {
var nativeResults = nativePlugins.reduce(into: [String: Bool](), { $0[$1] = false })
for plugin in nativePlugins {
let result = results[getAddress(plugin, native: true)]!
let fileName = getFileName(plugin, native: true)
let fileName = getPluginFileName(plugin, native: true)
if result {
if extractPlugin(plugin, native: true) {
nativeResults[plugin] = true
Expand All @@ -100,7 +98,7 @@ class Updater {
into: [String: Bool](), { $0[$1] = false })
for plugin in dataPlugins {
let result = results[getAddress(plugin, native: false)]!
let fileName = getFileName(plugin, native: false)
let fileName = getPluginFileName(plugin, native: false)
if result {
if extractPlugin(plugin, native: false) {
dataResults[plugin] = true
Expand Down
49 changes: 45 additions & 4 deletions src/config/plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Fcitx
import Logging
import SwiftUI
import SwiftyJSON
import UniformTypeIdentifiers

struct Plugin: Identifiable, Hashable {
let id: String
Expand Down Expand Up @@ -121,9 +122,12 @@ struct PluginView: View {
@State private var showCheckFailed = false
@State private var showDownloadFailed = false
@State private var showUpdateAvailable = false
@State private var showInvalidFileName = false

@ObservedObject private var pluginVM = PluginVM()

private let openPanel = NSOpenPanel()

func refreshPlugins() {
pluginVM.refreshPlugins()
}
Expand Down Expand Up @@ -255,10 +259,7 @@ struct PluginView: View {
processing = false
if needsRestart {
if autoRestart {
FcitxInputController.pluginManager.window?.performClose(_: nil)
DispatchQueue.main.async {
restartProcess()
}
restart()
} else {
promptRestart = true
}
Expand All @@ -269,6 +270,13 @@ struct PluginView: View {
})
}

private func restart() {
FcitxInputController.pluginManager.window?.performClose(_: nil)
DispatchQueue.main.async {
restartProcess()
}
}

var body: some View {
if processing {
ProgressView(value: downloadProgress, total: 1)
Expand Down Expand Up @@ -347,6 +355,34 @@ struct PluginView: View {
comment: ""))
}.disabled(selectedAvailable.isEmpty || processing)
.buttonStyle(.borderedProminent)
Button {
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = false
openPanel.allowedContentTypes = [UTType.init(filenameExtension: "bz2")!]
openPanel.directoryURL = URL(
fileURLWithPath: homeDir.appendingPathComponent("Downloads").localPath())
openPanel.begin { response in
if response == .OK {
for url in openPanel.urls {
let fileName = url.lastPathComponent
for pluginName in pluginMap.keys {
if fileName == getPluginFileName(pluginName, native: true) {
mkdirP(cacheDir.localPath())
let cacheFileURL = getCacheURL(pluginName, native: true)
let _ = copyFile(url, cacheFileURL)
let _ = exec(
"/usr/bin/xattr", ["-dr", "com.apple.quarantine", cacheFileURL.localPath()])
let _ = extractPlugin(pluginName, native: true)
restart()
}
}
}
showInvalidFileName = true
}
}
} label: {
Text("Install manually")
}
}
}
}.padding()
Expand Down Expand Up @@ -376,6 +412,11 @@ struct PluginView: View {
displayMode: .hud, type: .error(Color.red),
title: NSLocalizedString("Download failed", comment: ""))
}
.toast(isPresenting: $showInvalidFileName) {
AlertToast(
displayMode: .hud, type: .error(Color.red),
title: NSLocalizedString("Invalid file name", comment: ""))
}
}
}

Expand Down

0 comments on commit 0d53c41

Please sign in to comment.