feat: sparkle

(cherry picked from commit 9d0296ccf509aa463ecca4e01ebb1eeac1af2105)
This commit is contained in:
mrFq1 2024-09-21 22:11:55 +08:00
parent effce61b01
commit d1e8891f32
7 changed files with 41 additions and 157 deletions

View File

@ -53,6 +53,7 @@
01BCDB1A2C9ECD010028FA94 /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01BCDAE72C9ECD010028FA94 /* SidebarView.swift */; };
01BCDB1B2C9ECD010028FA94 /* SidebarLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01BCDAE52C9ECD010028FA94 /* SidebarLabel.swift */; };
01BCDB1D2C9EE2CF0028FA94 /* ProgressButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01BCDB1C2C9EE2CF0028FA94 /* ProgressButton.swift */; };
01BCDB212C9EEE260028FA94 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 01BCDB202C9EEE260028FA94 /* Sparkle */; };
01CA6BC12B6A1B3100E386D6 /* MetaServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01CA6BBF2B6A1B3100E386D6 /* MetaServer.swift */; };
01CA6BC22B6A1B3100E386D6 /* MetaServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01CA6BBF2B6A1B3100E386D6 /* MetaServer.swift */; };
01D567E42AD158B600CDA0AE /* MetaPrefs.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 01D567E12AD158B500CDA0AE /* MetaPrefs.storyboard */; };
@ -117,7 +118,6 @@
01F336032AD10D0B0048AF77 /* ProxyGroupMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F910AA23240134AF00116E95 /* ProxyGroupMenu.swift */; };
01F336042AD10D0B0048AF77 /* MenuItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4952C3BE2115C7CA004A4FA8 /* MenuItemFactory.swift */; };
01F336052AD10D0B0048AF77 /* MetaTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0162E74E2864B819007218A6 /* MetaTask.swift */; };
01F336062AD10D0B0048AF77 /* AutoUpgardeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F977FAAB2366790500C17F1F /* AutoUpgardeManager.swift */; };
01F336072AD10D0B0048AF77 /* RemoteConfigModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 499A485722ED715200F6C675 /* RemoteConfigModel.swift */; };
01F336082AD10D0B0048AF77 /* ProxyGroupMenuItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D176AA23575BB20093DD7B /* ProxyGroupMenuItemView.swift */; };
01F336092AD10D0B0048AF77 /* PrivilegedHelperManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49B4575C244F4A2A00463C39 /* PrivilegedHelperManager.swift */; };
@ -374,7 +374,6 @@
F939724B23A4B33500FE5A3F /* ClashProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClashProvider.swift; sourceTree = "<group>"; };
F939724D23A4DB0600FE5A3F /* DateFormatter+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+.swift"; sourceTree = "<group>"; };
F976275B23634DF8000EDEFE /* LoginServiceKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginServiceKit.swift; sourceTree = "<group>"; };
F977FAAB2366790500C17F1F /* AutoUpgardeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoUpgardeManager.swift; sourceTree = "<group>"; };
F977FAAD23669D6400C17F1F /* ConnectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionManager.swift; sourceTree = "<group>"; };
F9A7C0692306E874007163C7 /* com.metacubex.ClashX.ProxyConfigHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = com.metacubex.ClashX.ProxyConfigHelper; sourceTree = BUILT_PRODUCTS_DIR; };
F9E754CF239CC21F00CEE7CC /* WebPortalManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebPortalManager.swift; sourceTree = "<group>"; };
@ -397,6 +396,7 @@
01F336292AD10D0B0048AF77 /* PromiseKit in Frameworks */,
01BCDAAC2C9ECB3A0028FA94 /* DSFSparkline in Frameworks */,
01F3362A2AD10D0B0048AF77 /* KeyboardShortcuts in Frameworks */,
01BCDB212C9EEE260028FA94 /* Sparkle in Frameworks */,
01F3362B2AD10D0B0048AF77 /* Alamofire in Frameworks */,
01F3362C2AD10D0B0048AF77 /* CocoaLumberjack in Frameworks */,
01F3362D2AD10D0B0048AF77 /* Yams in Frameworks */,
@ -607,7 +607,6 @@
495BFB8721919B9800C8779D /* RemoteConfigManager.swift */,
4952C3BE2115C7CA004A4FA8 /* MenuItemFactory.swift */,
F935B2FB23085515009E4D33 /* SystemProxyManager.swift */,
F977FAAB2366790500C17F1F /* AutoUpgardeManager.swift */,
F977FAAD23669D6400C17F1F /* ConnectionManager.swift */,
F9E754CF239CC21F00CEE7CC /* WebPortalManager.swift */,
49B4575C244F4A2A00463C39 /* PrivilegedHelperManager.swift */,
@ -899,6 +898,7 @@
01F335CA2AD10D0B0048AF77 /* PromiseKit */,
01BCDAAB2C9ECB3A0028FA94 /* DSFSparkline */,
01BCDAB22C9ECB560028FA94 /* SwiftUIIntrospect */,
01BCDB202C9EEE260028FA94 /* Sparkle */,
);
productName = ClashX;
productReference = 01F336442AD10D0B0048AF77 /* ClashX Meta.app */;
@ -962,6 +962,7 @@
015B97842A4F31AE00F9FA4D /* XCRemoteSwiftPackageReference "PromiseKit" */,
01BCDAAA2C9ECB3A0028FA94 /* XCRemoteSwiftPackageReference "DSFSparkline" */,
01BCDAB12C9ECB560028FA94 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */,
01BCDB1F2C9EEE260028FA94 /* XCRemoteSwiftPackageReference "Sparkle" */,
);
productRefGroup = 49CF3B1E20CD7463001EBF94 /* Products */;
projectDirPath = "";
@ -1063,7 +1064,6 @@
01F336032AD10D0B0048AF77 /* ProxyGroupMenu.swift in Sources */,
01F336042AD10D0B0048AF77 /* MenuItemFactory.swift in Sources */,
01F336052AD10D0B0048AF77 /* MetaTask.swift in Sources */,
01F336062AD10D0B0048AF77 /* AutoUpgardeManager.swift in Sources */,
01BCDB1D2C9EE2CF0028FA94 /* ProgressButton.swift in Sources */,
01F336072AD10D0B0048AF77 /* RemoteConfigModel.swift in Sources */,
01F336082AD10D0B0048AF77 /* ProxyGroupMenuItemView.swift in Sources */,
@ -1196,7 +1196,7 @@
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
COMPRESS_PNG_FILES = YES;
CURRENT_PROJECT_VERSION = 0;
CURRENT_PROJECT_VERSION = 12;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
@ -1218,12 +1218,12 @@
"$(PROJECT_DIR)/ClashX",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = v1.0;
MARKETING_VERSION = v1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.metacubex.ClashX.meta;
PRODUCT_NAME = "ClashX Meta";
PROVISIONING_PROFILE_SPECIFIER = "";
STRIP_PNG_TEXT = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG SwiftUI_Version";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OBJC_BRIDGING_HEADER = "ClashX/ClashX-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@ -1242,7 +1242,7 @@
COMBINE_HIDPI_IMAGES = YES;
COMPRESS_PNG_FILES = YES;
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 0;
CURRENT_PROJECT_VERSION = 12;
DEAD_CODE_STRIPPING = YES;
DEPLOYMENT_POSTPROCESSING = YES;
DEVELOPMENT_TEAM = "";
@ -1265,13 +1265,13 @@
"$(PROJECT_DIR)/ClashX",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = v1.0;
MARKETING_VERSION = v1.2;
OTHER_CODE_SIGN_FLAGS = "--timestamp";
PRODUCT_BUNDLE_IDENTIFIER = com.metacubex.ClashX.meta;
PRODUCT_NAME = "ClashX Meta";
PROVISIONING_PROFILE_SPECIFIER = "";
STRIP_PNG_TEXT = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = SwiftUI_Version;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
SWIFT_OBJC_BRIDGING_HEADER = "ClashX/ClashX-Bridging-Header.h";
SWIFT_VERSION = 5.0;
};
@ -1602,6 +1602,14 @@
minimumVersion = 1.3.0;
};
};
01BCDB1F2C9EEE260028FA94 /* XCRemoteSwiftPackageReference "Sparkle" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sparkle-project/Sparkle";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.6.4;
};
};
01F335B72AD10D0B0048AF77 /* XCRemoteSwiftPackageReference "KeyboardShortcuts" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sindresorhus/KeyboardShortcuts.git";
@ -1703,6 +1711,11 @@
package = 01BCDAB12C9ECB560028FA94 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */;
productName = SwiftUIIntrospect;
};
01BCDB202C9EEE260028FA94 /* Sparkle */ = {
isa = XCSwiftPackageProductDependency;
package = 01BCDB1F2C9EEE260028FA94 /* XCRemoteSwiftPackageReference "Sparkle" */;
productName = Sparkle;
};
01F335B62AD10D0B0048AF77 /* KeyboardShortcuts */ = {
isa = XCSwiftPackageProductDependency;
package = 01F335B72AD10D0B0048AF77 /* XCRemoteSwiftPackageReference "KeyboardShortcuts" */;

View File

@ -1,5 +1,5 @@
{
"originHash" : "79f29dc60a8a95688aa73c0cce32f5496ed9744c56a5d38efc20f94aacd73360",
"originHash" : "8ca2b383ef3a419b80259396c281989a0b5151620017e615fd9f74e2a0dabf52",
"pins" : [
{
"identity" : "alamofire",
@ -91,6 +91,15 @@
"version" : "6.7.1"
}
},
{
"identity" : "sparkle",
"kind" : "remoteSourceControl",
"location" : "https://github.com/sparkle-project/Sparkle",
"state" : {
"revision" : "0ef1ee0220239b3776f433314515fd849025673f",
"version" : "2.6.4"
}
},
{
"identity" : "starscream",
"kind" : "remoteSourceControl",

View File

@ -21,7 +21,6 @@ private let MetaCoreMd5 = "WOSHIZIDONGSHENGCHENGDEA"
@main
class AppDelegate: NSObject, NSApplicationDelegate {
private(set) var statusItem: NSStatusItem!
@IBOutlet var checkForUpdateMenuItem: NSMenuItem!
@IBOutlet var statusMenu: NSMenu!
@IBOutlet var proxySettingMenuItem: NSMenuItem!
@ -116,8 +115,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
if WebPortalManager.hasWebProtal {
WebPortalManager.shared.addWebProtalMenuItem(&statusMenu)
}
AutoUpgardeManager.shared.setup()
AutoUpgardeManager.shared.setupCheckForUpdatesMenuItem(checkForUpdateMenuItem)
// install proxy helper
_ = ClashResourceManager.check()
PrivilegedHelperManager.shared.checkInstall()
@ -832,30 +830,6 @@ extension AppDelegate {
}
}
@IBAction func checkForUpdate(_ sender: NSMenuItem) {
let unc = NSUserNotificationCenter.default
AF.request("https://api.github.com/repos/MetaCubeX/ClashX.Meta/releases/latest").responseString {
guard $0.error == nil,
let data = $0.data,
let tagName = try? JSON(data: data)["tag_name"].string else {
unc.postUpdateNotice(msg: NSLocalizedString("Some thing failed.", comment: ""))
return
}
if tagName != AppVersionUtil.currentVersion {
let alert = NSAlert()
alert.messageText = NSLocalizedString("Open github release page to download ", comment: "") + "\(tagName)"
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
if alert.runModal() == .alertFirstButtonReturn {
NSWorkspace.shared.open(.init(string: "https://github.com/MetaCubeX/ClashX.Meta/releases/latest")!)
}
} else {
unc.postUpdateNotice(msg: NSLocalizedString("No new release found.", comment: ""))
}
}
}
@IBAction func updateGEO(_ sender: NSMenuItem) {
guard updateGeoTimer == nil else { return }
updateGeoTimer = Timer.scheduledTimer(withTimeInterval: 500, repeats: true) { [weak self] timer in

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23094"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -710,7 +711,6 @@
<outlet property="allowFromLanMenuItem" destination="Vz8-7n-vx6" id="Fzz-EG-huC"/>
<outlet property="apiPortMenuItem" destination="hwG-qf-DeZ" id="d6K-i7-yCo"/>
<outlet property="autoStartMenuItem" destination="B1J-XB-BiZ" id="xaS-h5-qd0"/>
<outlet property="checkForUpdateMenuItem" destination="p0T-J8-Emx" id="9BN-2j-QNB"/>
<outlet property="configSeparatorLine" destination="WzG-og-OyZ" id="hhn-AP-zKJ"/>
<outlet property="copyExportCommandExternalMenuItem" destination="7wl-vK-5JO" id="1Lu-Tu-FJy"/>
<outlet property="copyExportCommandMenuItem" destination="Jmb-PK-rMW" id="tiF-vV-Sqh"/>
@ -938,7 +938,7 @@
<menuItem title="Check Update" id="p0T-J8-Emx">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="checkForUpdate:" target="Voe-Tx-rLC" id="y8T-Su-dgd"/>
<action selector="checkForUpdates:" target="fth-rt-saN" id="lpG-w8-ucv"/>
</connections>
</menuItem>
<menuItem title="Log level" id="3Da-fL-Mzr">
@ -1028,7 +1028,7 @@
</items>
</menu>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="fth-rt-saN"/>
<customObject id="fth-rt-saN" customClass="SPUStandardUpdaterController"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
<userDefaultsController representsSharedInstance="YES" id="dwS-am-r7H"/>
</objects>

View File

@ -1,115 +0,0 @@
//
// AutoUpgardeManager.swift
// ClashX
//
// Created by yicheng on 2019/10/28.
// Copyright © 2019 west2online. All rights reserved.
//
import Cocoa
// import Sparkle
class AutoUpgardeManager: NSObject {
var checkForUpdatesMenuItem: NSMenuItem?
static let shared = AutoUpgardeManager()
// private var controller:SPUStandardUpdaterController?
private var current: Channel = {
if let value = UserDefaults.standard.object(forKey: "AutoUpgardeManager.current") as? Int,
let channel = Channel(rawValue: value) { return channel }
#if PRO_VERSION
return .appcenter
#else
return .stable
#endif
}() {
didSet {
UserDefaults.standard.set(current.rawValue, forKey: "AutoUpgardeManager.current")
}
}
private var allowSelectChannel: Bool {
return Bundle.main.object(forInfoDictionaryKey: "SUDisallowSelectChannel") as? Bool != true
}
// MARK: Public
func setup() {
// controller = SPUStandardUpdaterController(updaterDelegate: self, userDriverDelegate: nil)
}
func setupCheckForUpdatesMenuItem(_ item: NSMenuItem) {
// checkForUpdatesMenuItem = item
// checkForUpdatesMenuItem?.target = controller
// checkForUpdatesMenuItem?.action = #selector(SPUStandardUpdaterController.checkForUpdates(_:))
}
func addChannelMenuItem(_ button: NSPopUpButton) {
for channel in Channel.allCases {
button.addItem(withTitle: channel.title)
button.lastItem?.tag = channel.rawValue
}
button.target = self
button.action = #selector(didselectChannel(sender:))
button.selectItem(withTag: current.rawValue)
}
@objc func didselectChannel(sender: NSPopUpButton) {
guard let tag = sender.selectedItem?.tag, let channel = Channel(rawValue: tag) else { return }
current = channel
}
}
//extension AutoUpgardeManager: SPUUpdaterDelegate {
// func feedURLString(for updater: SPUUpdater) -> String? {
// guard WebPortalManager.hasWebProtal == false, allowSelectChannel else { return nil }
// return current.urlString
// }
//
// func updaterWillRelaunchApplication(_ updater: SPUUpdater) {
// SystemProxyManager.shared.disableProxy(port: 0, socksPort: 0, forceDisable: true)
// }
//}
// MARK: - Channel Enum
extension AutoUpgardeManager {
enum Channel: Int, CaseIterable {
#if !PRO_VERSION
case stable
case prelease
#endif
case appcenter
}
}
extension AutoUpgardeManager.Channel {
var title: String {
switch self {
#if !PRO_VERSION
case .stable:
return NSLocalizedString("Stable", comment: "")
case .prelease:
return NSLocalizedString("Prelease", comment: "")
#endif
case .appcenter:
return "Appcenter"
}
}
var urlString: String {
switch self {
#if !PRO_VERSION
case .stable:
return "https://yichengchen.github.io/clashX/appcast.xml"
case .prelease:
return "https://yichengchen.github.io/clashX/appcast_pre.xml"
#endif
case .appcenter:
#if PRO_VERSION
return "https://api.appcenter.ms/v0.1/public/sparkle/apps/1cd052f7-e118-4d13-87fb-35176f9702c1"
#else
return "https://api.appcenter.ms/v0.1/public/sparkle/apps/dce6e9a3-b6e3-4fd2-9f2d-35c767a99663"
#endif
}
}
}

View File

@ -129,6 +129,8 @@
<key>SUDisallowSelectChannel</key>
<false/>
<key>SUFeedURL</key>
<string>https://yichengchen.github.io/clashX/appcast.xml</string>
<string>https://raw.githubusercontent.com/MetaCubeX/clashX.meta/refs/heads/sparkle/appcast.xml</string>
<key>SUPublicEDKey</key>
<string>Jhu0RI5Vp02om6JhxYnFewD82GCV8v7U05toMFXb+7U=</string>
</dict>
</plist>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23094" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23094"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>