From b342fe9fd6b24f6d161e003d7156fc6600188e7b Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Fri, 17 May 2024 21:46:20 -0400 Subject: [PATCH 1/2] categorize plugins --- src/config/plugin.swift | 73 ++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/src/config/plugin.swift b/src/config/plugin.swift index 2417d52..0736582 100644 --- a/src/config/plugin.swift +++ b/src/config/plugin.swift @@ -21,18 +21,34 @@ private let pluginDirectory = libraryDir.appendingPathComponent("plugin") struct Plugin: Identifiable, Hashable { let id: String + let category: String + let github: String? } private let officialPlugins = [ - "anthy", - "chinese-addons", - "skk", - "hallelujah", - "rime", - "unikey", - "thai", - "lua", -].map { Plugin(id: $0) } + Plugin( + id: "anthy", category: NSLocalizedString("Japanese", comment: ""), github: "fcitx/fcitx5-anthy"), + Plugin( + id: "chinese-addons", category: NSLocalizedString("Chinese", comment: ""), + github: "fcitx/fcitx5-chinese-addons"), + Plugin( + id: "skk", category: NSLocalizedString("Japanese", comment: ""), github: "fcitx/fcitx5-skk"), + Plugin( + id: "hallelujah", category: NSLocalizedString("English", comment: ""), + github: "fcitx-contrib/fcitx5-hallelujah"), + Plugin( + id: "rime", category: NSLocalizedString("Generic", comment: ""), github: "fcitx/fcitx5-rime"), + Plugin( + id: "unikey", category: NSLocalizedString("Vietnamese", comment: ""), + github: "fcitx/fcitx5-unikey"), + Plugin( + id: "thai", category: NSLocalizedString("Thai", comment: ""), github: "fcitx/fcitx5-libthai"), + Plugin(id: "lua", category: NSLocalizedString("Other", comment: ""), github: "fcitx/fcitx5-lua"), +] + +private var pluginMap = officialPlugins.reduce(into: [String: Plugin]()) { result, plugin in + result[plugin.id] = plugin +} // fcitx5 doesn't unload addons from memory, so once loaded, we have to restart process to use an updated version. private var inMemoryPlugins: [String] = [] @@ -40,7 +56,9 @@ private var needsRestart = false private func getInstalledPlugins() -> [Plugin] { let names = getFileNamesWithExtension(pluginDirectory.localPath(), ".json") - return names.map { Plugin(id: $0) } + return names.map { + pluginMap[$0] ?? Plugin(id: $0, category: NSLocalizedString("Other", comment: ""), github: nil) + } } private func getFileName(_ plugin: String) -> String { @@ -144,6 +162,33 @@ struct PluginView: View { processing = false } + private func categorizePlugins(_ plugins: [Plugin]) -> some View { + let categorizedPlugins = plugins.reduce(into: [String: [Plugin]]()) { result, plugin in + result[plugin.category, default: []].append(plugin) + } + return ForEach(categorizedPlugins.keys.sorted(), id: \.self) { category in + Section(header: Text(category)) { + ForEach(categorizedPlugins[category]!) { plugin in + HStack { + Text(plugin.id) + if plugin.github != nil, + let url = URL(string: "https://github.com/\(plugin.github!)") + { + Button( + action: { + NSWorkspace.shared.open(url) + }, + label: { + Image(systemName: "arrow.up.forward.app.fill") + } + ).buttonStyle(.plain).help("\(url)") + } + } + } + } + } + } + private func install(_ autoRestart: Bool) { processing = true mkdirP(cacheDir.localPath()) @@ -253,9 +298,7 @@ struct PluginView: View { Text("Installed").font(.system(size: sectionHeaderSize)).frame( maxWidth: .infinity, alignment: .leading) List(selection: $selectedInstalled) { - ForEach(pluginVM.installedPlugins) { plugin in - Text(plugin.id) - } + categorizePlugins(pluginVM.installedPlugins) } Button("Uninstall", role: .destructive, action: uninstall).disabled( selectedInstalled.isEmpty || processing) @@ -264,9 +307,7 @@ struct PluginView: View { Text("Available").font(.system(size: sectionHeaderSize)).frame( maxWidth: .infinity, alignment: .leading) List(selection: $selectedAvailable) { - ForEach(pluginVM.availablePlugins) { plugin in - Text(plugin.id) - } + categorizePlugins(pluginVM.availablePlugins) }.contextMenu(forSelectionType: String.self) { items in } primaryAction: { items in // Double click From 0171cc975c6204d2d0619741f71a73f1b4b4dce2 Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Fri, 17 May 2024 22:45:04 -0400 Subject: [PATCH 2/2] i18n --- .github/workflows/ci.yml | 1 + assets/zh-Hans.lproj/Localizable.strings | Bin 8319 -> 15476 bytes 2 files changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06f3544..9c16c9d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ jobs: exit 1 fi done + file assets/zh-Hans.lproj/Localizable.strings | grep UTF-16 build: needs: lint diff --git a/assets/zh-Hans.lproj/Localizable.strings b/assets/zh-Hans.lproj/Localizable.strings index 780bca08a3d6d1f83be682b24cae2e934d9d7a49..981122d77ec4497297bda3e4f06df14d4c4b788c 100644 GIT binary patch literal 15476 zcmcgzTWlQF89uHGmBC5+1Zs+uX;f0z!gfdnRHmg^&ZTb1Y<6cIV>xly`)<8nZ@m|L zo!TUARAQFY>(XE=4j>+4=9c@0?ltU$^KGmaxS*y+-JDjQ(OGBl7e;D<-0 zdDm)bS5js9UeXABBt-UxkBpIaq-GMN6>w$R_S3P8fh)1AvwWJ6+`zlQi?#zOmzH?x zj=MVOBdIeYPP$4M^!L7SF>rPEwtZ+J^E4+HMb{GW#;8I4#`#N(I!}|0lSJ1N?P52@ z#~zC7hs1Xc`r9g7<1dZWo;Q7M^RiJdc`WQdL3RkaUR$JZmN-P;kZX{`Oxvu*Z`xM; zt4F!)g4i&v@m!FLQm-ptnlh92{NIkW7x?H+xSB1wk#13TM=pe}^K`_bZy8tHIr@$~ zk`_NQIJ^8*X6pR#sktdT%{H3+C>hNi&kLYFG%8)iFUU$xn zaY-sEW=Qv_1*k-*?s&JvPsutmL%|vo>rr62@6uWWB1rY4Q+(h3Eg~mm@cqx&Tj`r~ zEmP*528VZ@*kkulJu!cqjb$Rukx*9RoJT%wTgh=Hp*e02S2?%WnItVj`>GaLR1?NY z@0PeI8W>t?K`O-CsQ~O@r0ydBpQgK;Z zDYqSM@$I|t;j!+xNbuE5FJJZWl#Q?8=^^&7#|AVsNuQCOp(WIHOkg33W_-fzD?i~X zS^L878K8TpKbQf4mjK!8GCZ&?xFz^Z?6!U9(U;HsYVLaRE4#V;|A0#yyrifr(lM~T z!Z(#2a5IhS5bL8g=m%?&8ZR0qaZ-tQX(aRj$s$oNZ2>LU)!8jyrId@ zhGTv%>zNdFFM~M;IzUbF#zrssS=2oTztdW|X3JQ%g!c+d{CJ|7{KE&;w1A#5Mc$b+ z_yjM@<*6p=(~Dh2sAJQ$8hD$k)zuun=?1yqA1%T)+mfra3`6O!CT6ROm*C%jGJBWHb4n@G3c6k zxP8zPvhV!+F9#ec(>+fw%xmlJvMkYQx2+}pt(D@)_3-E6-GL{P;l;MKhkv#;2+dd1 zL0;#}=l!I8)m@i6*M9rnn{eL5WMl zHc4nGnPO zUF4h)z5Fy`p8aF}B>SB>PY7jjEpgWt@7aH0`G!m)i&Rq|<3HFLVbb zCcx#p;JvUOM{;Kf;we!T$$yF5wtsix&V2F+A0Nn}*lmZ(rZsYU>5p?#Ao@ZxDAud!)%gRwaOMx_ zU1t`wcG-ILq*5Ds8%G@IvIG3yV*jn_~t#x>oxmd$1eHq4J6NW+TdN- z9rmrVc$N=2HT9-;QzMEMnu@4ZXlgxqfcB{g02ViK3j zMgKbS=IlRCE|;HYn^=Psh1I)mTc(n1Xnc@z9q@N;?GMt`*s9zKj7+6hZi8-rgB>8q z7|wb;VV&5VZ@(4@M-WY3&q2pA?)Dieir9_rsd5jxeZ*^+{*is;^Ah8fkM!!0isy~! zcgJ@HSDinw%?JbJx$s`SqM-GO{n}pnH?LmT(v{f|nC>W9Cg$q5Q7s2|ZNb~Iw|zqe z?rL6-TXXdX>ws!+JTMwyHS+l>$Rqny9LJiaMsp@eO4X%%wT?B4wzbPotva8d6pN?k z4u&rWIOiA0H%k9b?z#*-Sr^Dv`8TjpL~=&nTP5vkZstvTCbcgI>H zr;FIld*bJ1T0xcPdG_KA5D&FGlQ{S9niLTkjh<|19v{*}v=#m|opZRUW6A{TDQm3k z{IH^~Q5_X&SPhi1hRD)$ncOwdMQ8imJS-6rxnn?HkLj`gFXfXI=(uG3Mm-(Z0q4>z zup`7MWT;kpA{KF`x(k!tk|mxbt~!W%&gB@-G2-bBIlFD#7pkZ7 z)bF%K`1VsBAq${4Rr5bM)^wjeJLptb-_5HQv-FH-7fm<%DT{8ZqWbAl&BqsC$&(=@ mU0^2>H^X<69nqh_6C3mT<$lA*HP%$kCwe#5YvU^=hyMpgSCT9M literal 8319 zcmbVS+fN%;8h_7UaTK-MZIr-nt4LK=t4&0k3bmwJNTj}wJ;(NJ#xtY2K>f0E5)5{X z!AZCV2$yhilYmKxz}SZTFI}HAQ?)yjK6dj+lJz5!x#-fq-ln*kuH7& z=hOLBvL|)iiXjXm&nBd-vMfEtts&KEf4U?^Yh#o$J>+=shif9w&!?Fv-OdEZE^9KBMu&47U{zesj{`b#rBLBsx z$T;}s%g=6hD-Qq6qh1f?-ar?`k&W5r<5Ejjw{qgT8Bug(TCQdq&hOeqG9~gZ-Aw18 zD)A2_lD98`qYsd0f%8RV(pPD^vPl;|K%JD*nK5do{?041R1&PDnCMus5#(J*Fjg}D zFI6xR&a#V`;|x6q+vhn#`qAuR7aUDbSB<~4lS$+KHp%;KI~G{7@ucbq3XxC2$#as~ zg!B?|@u~izx%@KxR>o~DEp$_X=5$eqPQg&FGMncFOL@h{t>_@xMN+Fu5qpknCehu5 ztvDjWg7Mc-N*hPHpj?pb#NU`B2Ddl{#Wd`HjY^&s@LY=-q~s zchHFDCXk!J$Wf9Q8SK}H26-F7$Q;JDt*I(Ddie2@;shxc=_WvI5P37pfYO}4#@!WYQTWl7i4v?yy9imhR%LvKholBsl|eTeO%B9kqi z$(@YJ$Abh({slHa#5qQ^Qk_;T3R|sjt*#kmgbL1c8{)2 zG?&-ml|Onwij%_sD3mAiM>1#541@es+los0M}T4Bmfc+ND$@lu>ZsX-Gm$Tk{X!As zz~LKi2=|-I3(eZRVA+LUt#CVh-vtYp3Z2j}7BnJEZgj-2u#sWTwIhFV7y7-7ir-@~ z(a?!pb6N^)1LcTmhnbYw2Wr6ZGNOObqS$a?)!-Q_7JV|;C+!{m#j2cxj?lIQ56gTq5_hI z66JbI>1Ma0uDMnv)hRhz4OU|?MWkST1oLhrTnp6GWa?> z_qF;l&DWbN`||xbDokZ%Z_UTm$nPW<2U%V17+ zwj}UJ-ByGlC5*qu$7QlJFLOpiu)T>UxG}W2ulOO+-jU`lk8luR$^6*OKVipjmm2nT!KRDAvt9$MJJ8ZVW`Jqm*md83@ z7Th!AakxVo0*8UWcr23aI4!ITkA>g6rm4G{)k(qJJghldMAJ36b24LMH}VI3V1Yx5 zTY#m5ZK<2F`>ksUp&7r4kU7^jJ=~6|=mEwSI$Jnemm3pw?f}x?pIPX(ikylPW8YPN zzmil^2<|LZR@jq@;c<*+^Dfh2l9-ub4u*Rdc1Vwpn@ef9dZD>Ic~TP1OwQ~F1}qM_ z1iJLvUy)kj+&3K0Vk;m}TWsNxo3e20f}v3<(CIRrc*tfvzJmAP)yT^{doQt7yWg>a zm)^Y#Vx*kEVv^tDhn(QJ_-XlX@}#ie4V$>FsO)}8L6$&z%iuogpt+ z(7v#zlR4RrDQNtBWVI1x_1wa(BAfRU(l0wb&A03hL8cc_5b3 X8=vF)J8z^|xBk1p8C}mk1ctu>o*``K