chore: release 26.0.27
This commit is contained in:
@@ -65,8 +65,9 @@ struct ServerInfo: Codable, Hashable, Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct PHPInterpreter: Codable, Hashable, Identifiable, Equatable {
|
struct PHPInterpreter: Codable, Hashable, Identifiable, Equatable {
|
||||||
var id: String { versionFull }
|
var id: String { [fullVersion, path ?? ""].joined(separator: "|") }
|
||||||
let version: String
|
let version: String
|
||||||
|
let fullVersion: String
|
||||||
let path: String?
|
let path: String?
|
||||||
let configFile: String?
|
let configFile: String?
|
||||||
let extensions: [String]
|
let extensions: [String]
|
||||||
@@ -75,6 +76,7 @@ struct ServerInfo: Codable, Hashable, Equatable {
|
|||||||
|
|
||||||
init(
|
init(
|
||||||
version: String,
|
version: String,
|
||||||
|
fullVersion: String? = nil,
|
||||||
path: String? = nil,
|
path: String? = nil,
|
||||||
configFile: String? = nil,
|
configFile: String? = nil,
|
||||||
extensions: [String] = [],
|
extensions: [String] = [],
|
||||||
@@ -82,6 +84,7 @@ struct ServerInfo: Codable, Hashable, Equatable {
|
|||||||
maxExecutionTime: String? = nil
|
maxExecutionTime: String? = nil
|
||||||
) {
|
) {
|
||||||
self.version = version
|
self.version = version
|
||||||
|
self.fullVersion = fullVersion ?? version
|
||||||
self.path = path
|
self.path = path
|
||||||
self.configFile = configFile
|
self.configFile = configFile
|
||||||
self.extensions = extensions
|
self.extensions = extensions
|
||||||
@@ -89,8 +92,8 @@ struct ServerInfo: Codable, Hashable, Equatable {
|
|||||||
self.maxExecutionTime = maxExecutionTime
|
self.maxExecutionTime = maxExecutionTime
|
||||||
}
|
}
|
||||||
|
|
||||||
var versionFull: String {
|
var versionWithPath: String {
|
||||||
var components = [version]
|
var components = [fullVersion]
|
||||||
if let path, !path.isEmpty {
|
if let path, !path.isEmpty {
|
||||||
components.append(path)
|
components.append(path)
|
||||||
}
|
}
|
||||||
@@ -162,10 +165,16 @@ struct ServerInfo: Codable, Hashable, Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var formattedServerTime: String {
|
var formattedServerTime: String {
|
||||||
guard let date = ServerInfo.isoFormatter.date(from: serverTime) else {
|
let normalizedServerTime = ServerInfo.normalizedServerTime(serverTime)
|
||||||
return serverTime
|
|
||||||
|
if let date = ServerInfo.serverTimeParsers
|
||||||
|
.lazy
|
||||||
|
.compactMap({ $0.date(from: normalizedServerTime) })
|
||||||
|
.first {
|
||||||
|
return ServerInfo.displayFormatter.string(from: date)
|
||||||
}
|
}
|
||||||
return ServerInfo.displayFormatter.string(from: date)
|
|
||||||
|
return serverTime
|
||||||
}
|
}
|
||||||
|
|
||||||
var operatingSystemSummary: String? {
|
var operatingSystemSummary: String? {
|
||||||
@@ -181,19 +190,42 @@ struct ServerInfo: Codable, Hashable, Equatable {
|
|||||||
// MARK: - Helpers & Sample Data
|
// MARK: - Helpers & Sample Data
|
||||||
|
|
||||||
extension ServerInfo {
|
extension ServerInfo {
|
||||||
private static let isoFormatter: ISO8601DateFormatter = {
|
private static let serverTimeParsers: [ISO8601DateFormatter] = {
|
||||||
let formatter = ISO8601DateFormatter()
|
let withFractional = ISO8601DateFormatter()
|
||||||
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds, .withColonSeparatorInTimeZone]
|
withFractional.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
|
||||||
return formatter
|
|
||||||
|
let withoutFractional = ISO8601DateFormatter()
|
||||||
|
withoutFractional.formatOptions = [.withInternetDateTime]
|
||||||
|
|
||||||
|
let noColonTimeZone = ISO8601DateFormatter()
|
||||||
|
noColonTimeZone.formatOptions = [.withFullDate, .withTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withTimeZone]
|
||||||
|
|
||||||
|
return [withFractional, withoutFractional, noColonTimeZone]
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private static let displayFormatter: DateFormatter = {
|
private static let displayFormatter: DateFormatter = {
|
||||||
let formatter = DateFormatter()
|
let formatter = DateFormatter()
|
||||||
|
formatter.locale = .autoupdatingCurrent
|
||||||
formatter.dateStyle = .medium
|
formatter.dateStyle = .medium
|
||||||
formatter.timeStyle = .medium
|
formatter.timeStyle = .medium
|
||||||
return formatter
|
return formatter
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
private static func normalizedServerTime(_ value: String) -> String {
|
||||||
|
if value.range(of: #"[+-]\d{2}:\d{2}$"#, options: .regularExpression) != nil {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
guard value.range(of: #"[+-]\d{4}$"#, options: .regularExpression) != nil else {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalized = value
|
||||||
|
let insertionIndex = normalized.index(normalized.endIndex, offsetBy: -2)
|
||||||
|
normalized.insert(":", at: insertionIndex)
|
||||||
|
return normalized
|
||||||
|
}
|
||||||
|
|
||||||
static let placeholder = ServerInfo(
|
static let placeholder = ServerInfo(
|
||||||
hostname: "preview.example.com",
|
hostname: "preview.example.com",
|
||||||
ipAddresses: ["192.168.1.1", "fe80::1"],
|
ipAddresses: ["192.168.1.1", "fe80::1"],
|
||||||
|
|||||||
@@ -278,6 +278,7 @@ private extension APIv2_12 {
|
|||||||
|
|
||||||
struct AdditionalInterpreter: Decodable {
|
struct AdditionalInterpreter: Decodable {
|
||||||
let version: String
|
let version: String
|
||||||
|
let versionFull: String?
|
||||||
let path: String?
|
let path: String?
|
||||||
let configFile: String?
|
let configFile: String?
|
||||||
}
|
}
|
||||||
@@ -398,6 +399,7 @@ private extension APIv2_12 {
|
|||||||
additionalPHPInterpreters: additionalPhpInterpreters?.map {
|
additionalPHPInterpreters: additionalPhpInterpreters?.map {
|
||||||
ServerInfo.PHPInterpreter(
|
ServerInfo.PHPInterpreter(
|
||||||
version: $0.version,
|
version: $0.version,
|
||||||
|
fullVersion: $0.versionFull,
|
||||||
path: $0.path,
|
path: $0.path,
|
||||||
configFile: $0.configFile,
|
configFile: $0.configFile,
|
||||||
extensions: [],
|
extensions: [],
|
||||||
|
|||||||
@@ -278,6 +278,7 @@ private extension APIv2_13 {
|
|||||||
|
|
||||||
struct AdditionalInterpreter: Decodable {
|
struct AdditionalInterpreter: Decodable {
|
||||||
let version: String
|
let version: String
|
||||||
|
let versionFull: String?
|
||||||
let path: String?
|
let path: String?
|
||||||
let configFile: String?
|
let configFile: String?
|
||||||
}
|
}
|
||||||
@@ -398,6 +399,7 @@ private extension APIv2_13 {
|
|||||||
additionalPHPInterpreters: additionalPhpInterpreters?.map {
|
additionalPHPInterpreters: additionalPhpInterpreters?.map {
|
||||||
ServerInfo.PHPInterpreter(
|
ServerInfo.PHPInterpreter(
|
||||||
version: $0.version,
|
version: $0.version,
|
||||||
|
fullVersion: $0.versionFull,
|
||||||
path: $0.path,
|
path: $0.path,
|
||||||
configFile: $0.configFile,
|
configFile: $0.configFile,
|
||||||
extensions: [],
|
extensions: [],
|
||||||
|
|||||||
@@ -5,12 +5,6 @@
|
|||||||
// Created by tracer on 03.04.25.
|
// Created by tracer on 03.04.25.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
|
||||||
// ResourcesBarRow.swift
|
|
||||||
// iKeyMon
|
|
||||||
//
|
|
||||||
// Created by tracer on 31.03.25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,13 @@ struct GeneralView: View {
|
|||||||
if interpreters.isEmpty {
|
if interpreters.isEmpty {
|
||||||
return ["None"]
|
return ["None"]
|
||||||
}
|
}
|
||||||
return interpreters.map { $0.versionFull }
|
let versions = interpreters
|
||||||
|
.map { $0.fullVersion }
|
||||||
|
.filter { !$0.isEmpty }
|
||||||
|
if versions.isEmpty {
|
||||||
|
return ["None"]
|
||||||
|
}
|
||||||
|
return [versions.joined(separator: " • ")]
|
||||||
}(),
|
}(),
|
||||||
monospaced: true
|
monospaced: true
|
||||||
)
|
)
|
||||||
|
|||||||
36
Sparkle/appcast.xml
vendored
36
Sparkle/appcast.xml
vendored
@@ -1,30 +1,30 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||||
<rss xmlns:ns0="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
|
<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
|
||||||
<channel>
|
<channel>
|
||||||
<title>iKeyMon</title>
|
<title>iKeyMon</title>
|
||||||
|
<item>
|
||||||
|
<title>26.0.27</title>
|
||||||
|
<pubDate>Sun, 07 Dec 2025 16:47:33 +0100</pubDate>
|
||||||
|
<sparkle:version>57</sparkle:version>
|
||||||
|
<sparkle:shortVersionString>26.0.27</sparkle:shortVersionString>
|
||||||
|
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
||||||
|
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/iKeyMon-26.0.27.zip" length="4811492" type="application/octet-stream" sparkle:edSignature="6aEv0ii20pAkIl8kYWNkHM7+8APyDQtsus0SkF3C7/7q2X73HAsrsskNXjiiq0YF6bPVNAEs5y8G8GpwmerrCw=="/>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title>26.0.21</title>
|
<title>26.0.21</title>
|
||||||
<pubDate>Wed, 26 Nov 2025 18:44:41 +0100</pubDate>
|
<pubDate>Wed, 26 Nov 2025 18:44:41 +0100</pubDate>
|
||||||
<ns0:version>49</ns0:version>
|
<sparkle:version>49</sparkle:version>
|
||||||
<ns0:shortVersionString>26.0.21</ns0:shortVersionString>
|
<sparkle:shortVersionString>26.0.21</sparkle:shortVersionString>
|
||||||
<ns0:minimumSystemVersion>15.2</ns0:minimumSystemVersion>
|
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
||||||
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.21/iKeyMon-26.0.21.zip" length="4802995" type="application/octet-stream" ns0:edSignature="bYXN15YyKlSmHKNXPizEW2WrVXQSgD5XOgbtzOYNL+maG8DB/jZ08A+cYtGgqUeSRd+X6Z5Ue+Tpdn4/ewsFBw==" />
|
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.21/iKeyMon-26.0.21.zip" length="4802995" type="application/octet-stream" sparkle:edSignature="bYXN15YyKlSmHKNXPizEW2WrVXQSgD5XOgbtzOYNL+maG8DB/jZ08A+cYtGgqUeSRd+X6Z5Ue+Tpdn4/ewsFBw=="/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title>26.0.20</title>
|
<title>26.0.20</title>
|
||||||
<pubDate>Wed, 26 Nov 2025 18:36:41 +0100</pubDate>
|
<pubDate>Wed, 26 Nov 2025 18:36:41 +0100</pubDate>
|
||||||
<ns0:version>47</ns0:version>
|
<sparkle:version>47</sparkle:version>
|
||||||
<ns0:shortVersionString>26.0.20</ns0:shortVersionString>
|
<sparkle:shortVersionString>26.0.20</sparkle:shortVersionString>
|
||||||
<ns0:minimumSystemVersion>15.2</ns0:minimumSystemVersion>
|
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
||||||
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.20/iKeyMon-26.0.20.zip" length="4802865" type="application/octet-stream" ns0:edSignature="hCJu2I1Db/TaU6pCs1gZi9EO5igr49Fjt/VNnyD8+jm45WINuhzGc4lShcLPxUQTy4iNHnVhmOPYwlthVMXPAg==" />
|
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.20/iKeyMon-26.0.20.zip" length="4802865" type="application/octet-stream" sparkle:edSignature="hCJu2I1Db/TaU6pCs1gZi9EO5igr49Fjt/VNnyD8+jm45WINuhzGc4lShcLPxUQTy4iNHnVhmOPYwlthVMXPAg=="/>
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<title>26.0.16</title>
|
|
||||||
<pubDate>Tue, 25 Nov 2025 18:34:19 +0100</pubDate>
|
|
||||||
<ns0:version>39</ns0:version>
|
|
||||||
<ns0:shortVersionString>26.0.16</ns0:shortVersionString>
|
|
||||||
<ns0:minimumSystemVersion>15.2</ns0:minimumSystemVersion>
|
|
||||||
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.16/iKeyMon-26.0.16.zip" length="4801351" type="application/octet-stream" ns0:edSignature="lbQEpxEElRxwyRdm0LQIxsnfh8o8Kt66wQlcl4PBs68lBmjkq0b/5EsVCElWQb0Nei/GCk6I/m2mSNL7mA3wBQ==" />
|
|
||||||
</item>
|
</item>
|
||||||
</channel>
|
</channel>
|
||||||
</rss>
|
</rss>
|
||||||
@@ -310,7 +310,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 56;
|
CURRENT_PROJECT_VERSION = 57;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -325,7 +325,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 26.0.26;
|
MARKETING_VERSION = 26.0.27;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.24unix.iKeyMon;
|
PRODUCT_BUNDLE_IDENTIFIER = net.24unix.iKeyMon;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
@@ -341,7 +341,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 56;
|
CURRENT_PROJECT_VERSION = 57;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -356,7 +356,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 26.0.26;
|
MARKETING_VERSION = 26.0.27;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.24unix.iKeyMon;
|
PRODUCT_BUNDLE_IDENTIFIER = net.24unix.iKeyMon;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ generate_appcast() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local sparkle_cache="$HOME/Library/Caches/Sparkle_generate_appcast"
|
||||||
|
rm -rf "$sparkle_cache"
|
||||||
|
|
||||||
local output="$SPARKLE_APPCAST_OUTPUT"
|
local output="$SPARKLE_APPCAST_OUTPUT"
|
||||||
mkdir -p "$(dirname "$output")"
|
mkdir -p "$(dirname "$output")"
|
||||||
local staging_dir
|
local staging_dir
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"marketing_version": "26.0.26"
|
"marketing_version": "26.0.27"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user