From 7d8e83c4737313f330940a9e84205460a8063787 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Sun, 5 Jun 2022 22:37:16 +0800 Subject: [PATCH 01/56] Add imports where required, remove custom equitable conformance Also testing out performance without custom equitables, and seeing if that irons out any bugs --- Swiftcord.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/swiftpm/Package.resolved | 18 +++++++++--------- Swiftcord/SwiftcordApp.swift | 6 +----- .../Extensions/DiscordAPI/Array.Channel+.swift | 2 +- .../Utils/Extensions/DiscordAPI/Channel+.swift | 2 +- .../Extensions/DiscordAPI/CurrentUser+.swift | 1 + .../Utils/Extensions/DiscordAPI/Guild+.swift | 1 + .../Utils/Extensions/DiscordAPI/Message+.swift | 2 +- .../Utils/Extensions/DiscordAPI/User+.swift | 1 + Swiftcord/Utils/Extensions/MessagesView+.swift | 1 + .../MergeStructs/MergePartialMessage.swift | 1 + Swiftcord/Views/ContentView.swift | 3 +-- Swiftcord/Views/EnvObjects/UIStateEnv.swift | 9 +-------- Swiftcord/Views/Message/AttachmentView.swift | 1 + Swiftcord/Views/Message/EmbedView.swift | 2 +- Swiftcord/Views/Message/MessageView.swift | 7 ++----- Swiftcord/Views/Message/MessagesView.swift | 7 ++----- .../Views/Message/ReferenceMessageView.swift | 1 + Swiftcord/Views/Message/StickerView.swift | 1 + Swiftcord/Views/Server/ChannelButton.swift | 1 + Swiftcord/Views/Server/ChannelList.swift | 7 ++----- Swiftcord/Views/Server/ServerView.swift | 10 +++------- .../Settings/Misc/DebugSettingsView.swift | 1 + Swiftcord/Views/Settings/SettingsView.swift | 1 + .../User/UserSettingsAccountView.swift | 1 + .../User/UserSettingsProfileView.swift | 2 +- .../Views/Settings/User/UserSettingsView.swift | 1 + Swiftcord/Views/User/CurrentUserFooter.swift | 1 + .../User/Profile/LargeUserProfileView.swift | 2 +- .../User/Profile/MiniUserProfileView.swift | 1 + .../Views/User/Profile/ProfileBadges.swift | 1 + Swiftcord/Views/User/UserAvatarView.swift | 3 ++- 32 files changed, 47 insertions(+), 53 deletions(-) diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 1a6e18c1..67bba8b0 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -171,6 +171,7 @@ DA7720CF283F184100D3C335 /* NavigationCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCommands.swift; sourceTree = ""; }; DA97BA892848737C00059FD7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; DA97BA8B2849C0FA00059FD7 /* Cache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cache.swift; sourceTree = ""; }; + DAAA22AA284CF3D100C1975E /* DiscordKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DiscordKit; path = ../DiscordKit; sourceTree = ""; }; DAAFB5BB282A570D00807B54 /* CircularProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircularProgressView.swift; sourceTree = ""; }; DAAFB5C0282A64CD00807B54 /* LoFiMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoFiMessageView.swift; sourceTree = ""; }; DAAFB5C2282AA5C700807B54 /* MessageInfoBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageInfoBarView.swift; sourceTree = ""; }; @@ -281,6 +282,7 @@ DA4A887B27C0AF3000720909 = { isa = PBXGroup; children = ( + DAAA22AA284CF3D100C1975E /* DiscordKit */, 36004E1C283D63E500F0BA73 /* .swiftlint.yml */, DA4A888627C0AF3000720909 /* Swiftcord */, DA4A891727C4B0DF00720909 /* README.md */, diff --git a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved index b4ae6ff0..4a69a2ee 100644 --- a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -9,15 +9,6 @@ "version" : "4.4.2" } }, - { - "identity" : "discordkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SwiftcordApp/DiscordKit", - "state" : { - "branch" : "main", - "revision" : "3674512a16def56441f0a46b14d19bf0898d0782" - } - }, { "identity" : "lottie-ios", "kind" : "remoteSourceControl", @@ -54,6 +45,15 @@ "version" : "2.1.0" } }, + { + "identity" : "swift-docc-plugin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-docc-plugin", + "state" : { + "revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6", + "version" : "1.0.0" + } + }, { "identity" : "swiftui-cached-async-image", "kind" : "remoteSourceControl", diff --git a/Swiftcord/SwiftcordApp.swift b/Swiftcord/SwiftcordApp.swift index f68ebdfb..0befcba6 100644 --- a/Swiftcord/SwiftcordApp.swift +++ b/Swiftcord/SwiftcordApp.swift @@ -12,7 +12,7 @@ import SwiftUI let appName = Bundle.main.infoDictionary?[kCFBundleNameKey as String] as? String @main -struct SwiftcordApp: App, Equatable { +struct SwiftcordApp: App { @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate let persistenceController = PersistenceController.shared @StateObject var updaterViewModel = UpdaterViewModel() @@ -53,8 +53,4 @@ struct SwiftcordApp: App, Equatable { // .environment(\.locale, .init(identifier: "zh-Hans")) } } - - static func == (lhs: SwiftcordApp, rhs: SwiftcordApp) -> Bool { - lhs.gateway == rhs.gateway && lhs.state == rhs.state - } } diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/Array.Channel+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/Array.Channel+.swift index 8359990d..6389df57 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/Array.Channel+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/Array.Channel+.swift @@ -5,7 +5,7 @@ // Created by royal on 14/05/2022. // -import DiscordKit +import DiscordKitCore extension Array where Element == Channel { func discordSorted() -> Self { diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/Channel+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/Channel+.swift index cd59d820..400461b1 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/Channel+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/Channel+.swift @@ -5,7 +5,7 @@ // Created by royal on 14/05/2022. // -import DiscordKit +import DiscordKitCore extension Channel { func label(_ users: [Snowflake: User] = [:]) -> String? { diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/CurrentUser+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/CurrentUser+.swift index 739ba3e2..e6be200f 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/CurrentUser+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/CurrentUser+.swift @@ -7,6 +7,7 @@ import Foundation import DiscordKit +import DiscordKitCore extension CurrentUser { func avatarURL(size: Int = 160) -> URL { diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/Guild+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/Guild+.swift index e42e9d69..b8d069d1 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/Guild+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/Guild+.swift @@ -6,6 +6,7 @@ // import DiscordKit +import DiscordKitCore extension Guild { var isDMChannel: Bool { id == "@me" } diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/Message+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/Message+.swift index 2a3abbec..6a4037c2 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/Message+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/Message+.swift @@ -6,7 +6,7 @@ // import Foundation -import DiscordKit +import DiscordKitCore extension Message { func messageIsShrunk(prev: Message) -> Bool { diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/User+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/User+.swift index 531caafa..95aa360b 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/User+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/User+.swift @@ -7,6 +7,7 @@ import Foundation import DiscordKit +import DiscordKitCore extension User { func avatarURL(size: Int = 160) -> URL { diff --git a/Swiftcord/Utils/Extensions/MessagesView+.swift b/Swiftcord/Utils/Extensions/MessagesView+.swift index e8baa9bb..a81a9a2a 100644 --- a/Swiftcord/Utils/Extensions/MessagesView+.swift +++ b/Swiftcord/Utils/Extensions/MessagesView+.swift @@ -7,6 +7,7 @@ import Foundation import DiscordKit +import DiscordKitCore extension MessagesView { internal func fetchMoreMessages() { diff --git a/Swiftcord/Utils/MergeStructs/MergePartialMessage.swift b/Swiftcord/Utils/MergeStructs/MergePartialMessage.swift index 609906f8..f65a3a5a 100644 --- a/Swiftcord/Utils/MergeStructs/MergePartialMessage.swift +++ b/Swiftcord/Utils/MergeStructs/MergePartialMessage.swift @@ -9,6 +9,7 @@ import Foundation import DiscordKit +import DiscordKitCore extension Message { mutating func mergeWithPartialMsg(_ partial: PartialMessage) { diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index 36308041..66bbd4a1 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -9,6 +9,7 @@ import SwiftUI import CoreData import os import DiscordKit +import DiscordKitCore import DiscordKitCommon struct CustomHorizontalDivider: View { @@ -129,8 +130,6 @@ struct ContentView: View { ) } - // Using the .equatable() modifier on this View causes a swift-frontend - // bus error when compiling for release. I have no idea why that happens. ServerView( guild: selectedGuildID == nil ? nil diff --git a/Swiftcord/Views/EnvObjects/UIStateEnv.swift b/Swiftcord/Views/EnvObjects/UIStateEnv.swift index 0d57a9a3..6715335e 100644 --- a/Swiftcord/Views/EnvObjects/UIStateEnv.swift +++ b/Swiftcord/Views/EnvObjects/UIStateEnv.swift @@ -13,16 +13,9 @@ enum LoadingState { case messageLoad } -class UIState: ObservableObject, Equatable { +class UIState: ObservableObject { @Published var loadingState: LoadingState = .initial @Published var attemptLogin = false @Published var selfMute = false @Published var selfDeaf = false - - static func == (lhs: UIState, rhs: UIState) -> Bool { - return lhs.loadingState == rhs.loadingState && - lhs.attemptLogin == rhs.attemptLogin && - lhs.selfMute == rhs.selfMute && - lhs.selfDeaf == rhs.selfDeaf - } } diff --git a/Swiftcord/Views/Message/AttachmentView.swift b/Swiftcord/Views/Message/AttachmentView.swift index dc2a2204..0174b9ed 100644 --- a/Swiftcord/Views/Message/AttachmentView.swift +++ b/Swiftcord/Views/Message/AttachmentView.swift @@ -11,6 +11,7 @@ import AVKit import CachedAsyncImage import QuickLook import DiscordKit +import DiscordKitCore struct AttachmentError: View { let height: Int diff --git a/Swiftcord/Views/Message/EmbedView.swift b/Swiftcord/Views/Message/EmbedView.swift index 70c1fcea..baa645b5 100644 --- a/Swiftcord/Views/Message/EmbedView.swift +++ b/Swiftcord/Views/Message/EmbedView.swift @@ -7,7 +7,7 @@ import SwiftUI import CachedAsyncImage -import DiscordKit +import DiscordKitCore struct EmbedView: View { let embed: Embed diff --git a/Swiftcord/Views/Message/MessageView.swift b/Swiftcord/Views/Message/MessageView.swift index ea74a618..d9555bf9 100644 --- a/Swiftcord/Views/Message/MessageView.swift +++ b/Swiftcord/Views/Message/MessageView.swift @@ -9,6 +9,7 @@ import SwiftUI import CachedAsyncImage import DiscordKit +import DiscordKitCore struct NonUserBadge: View { let flags: Int? @@ -34,7 +35,7 @@ struct NonUserBadge: View { } } -struct MessageView: View, Equatable { +struct MessageView: View { let message: Message let shrunk: Bool let lineSpacing = 4 as CGFloat @@ -215,10 +216,6 @@ struct MessageView: View, Equatable { } } } - - static func == (lhs: MessageView, rhs: MessageView) -> Bool { - lhs.message == rhs.message - } } private extension MessageView { diff --git a/Swiftcord/Views/Message/MessagesView.swift b/Swiftcord/Views/Message/MessagesView.swift index b7397294..8c74c0eb 100644 --- a/Swiftcord/Views/Message/MessagesView.swift +++ b/Swiftcord/Views/Message/MessagesView.swift @@ -7,6 +7,7 @@ import SwiftUI import DiscordKit +import DiscordKitCore import CachedAsyncImage extension View { @@ -84,11 +85,7 @@ struct DayDividerView: View { } } -struct MessagesView: View, Equatable { - static func == (lhs: MessagesView, rhs: MessagesView) -> Bool { - lhs.messages == rhs.messages && lhs.attachments == rhs.attachments - } - +struct MessagesView: View { @State internal var reachedTop = false @State internal var messages: [Message] = [] @State internal var newMessage = " " diff --git a/Swiftcord/Views/Message/ReferenceMessageView.swift b/Swiftcord/Views/Message/ReferenceMessageView.swift index cafd52d1..6df018f8 100644 --- a/Swiftcord/Views/Message/ReferenceMessageView.swift +++ b/Swiftcord/Views/Message/ReferenceMessageView.swift @@ -7,6 +7,7 @@ import SwiftUI import DiscordKit +import DiscordKitCore import CachedAsyncImage struct ReferenceMessageView: View { diff --git a/Swiftcord/Views/Message/StickerView.swift b/Swiftcord/Views/Message/StickerView.swift index d2705107..dd31049c 100644 --- a/Swiftcord/Views/Message/StickerView.swift +++ b/Swiftcord/Views/Message/StickerView.swift @@ -8,6 +8,7 @@ import SwiftUI import Lottie import DiscordKit +import DiscordKitCore import CachedAsyncImage struct StickerLoadingView: View { diff --git a/Swiftcord/Views/Server/ChannelButton.swift b/Swiftcord/Views/Server/ChannelButton.swift index 5a7eb1d2..95c32069 100644 --- a/Swiftcord/Views/Server/ChannelButton.swift +++ b/Swiftcord/Views/Server/ChannelButton.swift @@ -7,6 +7,7 @@ import SwiftUI import DiscordKit +import DiscordKitCore import CachedAsyncImage struct ChannelButton: View { diff --git a/Swiftcord/Views/Server/ChannelList.swift b/Swiftcord/Views/Server/ChannelList.swift index 8c9b58c6..c96d2b8b 100644 --- a/Swiftcord/Views/Server/ChannelList.swift +++ b/Swiftcord/Views/Server/ChannelList.swift @@ -7,8 +7,9 @@ import SwiftUI import DiscordKit +import DiscordKitCore -struct ChannelList: View, Equatable { +struct ChannelList: View { let channels: [Channel] @Binding var selCh: Channel? @@ -52,8 +53,4 @@ struct ChannelList: View, Equatable { // this overlay applies a border on the bottom edge of the view .overlay(Rectangle().fill(Color(nsColor: .separatorColor)).frame(width: nil, height: 1, alignment: .bottom), alignment: .top) } - - static func == (lhs: Self, rhs: Self) -> Bool { - lhs.channels == rhs.channels && lhs.selCh == rhs.selCh - } } diff --git a/Swiftcord/Views/Server/ServerView.swift b/Swiftcord/Views/Server/ServerView.swift index b4b06908..59a0e530 100644 --- a/Swiftcord/Views/Server/ServerView.swift +++ b/Swiftcord/Views/Server/ServerView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import DiscordKitCore import DiscordKit class ServerContext: ObservableObject { @@ -15,7 +16,7 @@ class ServerContext: ObservableObject { @Published public var roles: [Role] = [] } -struct ServerView: View, Equatable { +struct ServerView: View { let guild: Guild? @State private var evtID: EventDispatch.HandlerIdentifier? @State private var mediaCenterOpen: Bool = false @@ -84,7 +85,6 @@ struct ServerView: View, Equatable { VStack(spacing: 0) { if let guild = guild { ChannelList(channels: guild.channels!, selCh: $serverCtx.channel) - .equatable() .toolbar { ToolbarItem { Text(guild.name == "DMs" ? "dm" : "\(guild.name)") @@ -118,7 +118,7 @@ struct ServerView: View, Equatable { } if serverCtx.channel != nil { - MessagesView().equatable() + MessagesView() } else { VStack(spacing: 24) { Image(serverCtx.guild?.id == "@me" ? "NoDMs" : "NoGuildChannels") @@ -207,8 +207,4 @@ struct ServerView: View, Equatable { if let evtID = evtID { _ = gateway.onEvent.removeHandler(handler: evtID) } } } - - static func == (lhs: Self, rhs: Self) -> Bool { - lhs.guild == rhs.guild - } } diff --git a/Swiftcord/Views/Settings/Misc/DebugSettingsView.swift b/Swiftcord/Views/Settings/Misc/DebugSettingsView.swift index 8dab423c..90fec886 100644 --- a/Swiftcord/Views/Settings/Misc/DebugSettingsView.swift +++ b/Swiftcord/Views/Settings/Misc/DebugSettingsView.swift @@ -7,6 +7,7 @@ import SwiftUI import DiscordKit +import DiscordKitCore struct DebugTableItem: Identifiable { let id = UUID() diff --git a/Swiftcord/Views/Settings/SettingsView.swift b/Swiftcord/Views/Settings/SettingsView.swift index 0e7c6f8c..d531155b 100644 --- a/Swiftcord/Views/Settings/SettingsView.swift +++ b/Swiftcord/Views/Settings/SettingsView.swift @@ -7,6 +7,7 @@ import SwiftUI import DiscordKit +import DiscordKitCore struct SettingsView: View { @EnvironmentObject var gateway: DiscordGateway diff --git a/Swiftcord/Views/Settings/User/UserSettingsAccountView.swift b/Swiftcord/Views/Settings/User/UserSettingsAccountView.swift index 277003cb..0468e7ac 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsAccountView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsAccountView.swift @@ -7,6 +7,7 @@ import SwiftUI import DiscordKit +import DiscordKitCore struct UserSettingsAccountView: View { let user: CurrentUser diff --git a/Swiftcord/Views/Settings/User/UserSettingsProfileView.swift b/Swiftcord/Views/Settings/User/UserSettingsProfileView.swift index a240966e..47bf87ab 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsProfileView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsProfileView.swift @@ -6,7 +6,7 @@ // import SwiftUI -import DiscordKit +import DiscordKitCore struct UserSettingsProfileView: View { let user: CurrentUser diff --git a/Swiftcord/Views/Settings/User/UserSettingsView.swift b/Swiftcord/Views/Settings/User/UserSettingsView.swift index 24b1131c..75805889 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsView.swift @@ -7,6 +7,7 @@ import SwiftUI import DiscordKit +import DiscordKitCore struct UserSettingsView: View { let user: CurrentUser diff --git a/Swiftcord/Views/User/CurrentUserFooter.swift b/Swiftcord/Views/User/CurrentUserFooter.swift index 8c524eb1..6de744f0 100644 --- a/Swiftcord/Views/User/CurrentUserFooter.swift +++ b/Swiftcord/Views/User/CurrentUserFooter.swift @@ -9,6 +9,7 @@ import SwiftUI import CachedAsyncImage import DiscordKit +import DiscordKitCore struct CurrentUserFooter: View { let user: CurrentUser diff --git a/Swiftcord/Views/User/Profile/LargeUserProfileView.swift b/Swiftcord/Views/User/Profile/LargeUserProfileView.swift index 3187bd8c..25df2029 100644 --- a/Swiftcord/Views/User/Profile/LargeUserProfileView.swift +++ b/Swiftcord/Views/User/Profile/LargeUserProfileView.swift @@ -7,7 +7,7 @@ import SwiftUI import CachedAsyncImage -import DiscordKit +import DiscordKitCore struct LargeUserProfile: View { let user: CurrentUser diff --git a/Swiftcord/Views/User/Profile/MiniUserProfileView.swift b/Swiftcord/Views/User/Profile/MiniUserProfileView.swift index fafb8428..d794c2ad 100644 --- a/Swiftcord/Views/User/Profile/MiniUserProfileView.swift +++ b/Swiftcord/Views/User/Profile/MiniUserProfileView.swift @@ -7,6 +7,7 @@ import SwiftUI import DiscordKit +import DiscordKitCore import CachedAsyncImage struct MiniUserProfileView: View { diff --git a/Swiftcord/Views/User/Profile/ProfileBadges.swift b/Swiftcord/Views/User/Profile/ProfileBadges.swift index b028ebbe..a37a1fa9 100644 --- a/Swiftcord/Views/User/Profile/ProfileBadges.swift +++ b/Swiftcord/Views/User/Profile/ProfileBadges.swift @@ -6,6 +6,7 @@ // import DiscordKit +import DiscordKitCore import SwiftUI struct ProfileBadges: View, Equatable { diff --git a/Swiftcord/Views/User/UserAvatarView.swift b/Swiftcord/Views/User/UserAvatarView.swift index cbb349d3..36f36d96 100644 --- a/Swiftcord/Views/User/UserAvatarView.swift +++ b/Swiftcord/Views/User/UserAvatarView.swift @@ -7,6 +7,7 @@ import SwiftUI import CachedAsyncImage +import DiscordKitCore import DiscordKit struct UserAvatarView: View, Equatable { @@ -22,7 +23,7 @@ struct UserAvatarView: View, Equatable { @EnvironmentObject var ctx: ServerContext @EnvironmentObject var gateway: DiscordGateway - static let profileCache = Cache() + static private let profileCache = Cache() var body: some View { let avatarURL = user.avatarURL(size: size == 40 ? 160 : Int(size)*2) From 949fcefbaf0b0b16fe9627aed0e94bc84191b33a Mon Sep 17 00:00:00 2001 From: vinkwok Date: Sun, 5 Jun 2022 23:21:29 +0800 Subject: [PATCH 02/56] Rely on corresponding DiscordKit branch (rearchitect) --- Swiftcord.xcodeproj/project.pbxproj | 4 +--- .../xcshareddata/swiftpm/Package.resolved | 18 +++++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 67bba8b0..61b6cf5a 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -171,7 +171,6 @@ DA7720CF283F184100D3C335 /* NavigationCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCommands.swift; sourceTree = ""; }; DA97BA892848737C00059FD7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; DA97BA8B2849C0FA00059FD7 /* Cache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cache.swift; sourceTree = ""; }; - DAAA22AA284CF3D100C1975E /* DiscordKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DiscordKit; path = ../DiscordKit; sourceTree = ""; }; DAAFB5BB282A570D00807B54 /* CircularProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircularProgressView.swift; sourceTree = ""; }; DAAFB5C0282A64CD00807B54 /* LoFiMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoFiMessageView.swift; sourceTree = ""; }; DAAFB5C2282AA5C700807B54 /* MessageInfoBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageInfoBarView.swift; sourceTree = ""; }; @@ -282,7 +281,6 @@ DA4A887B27C0AF3000720909 = { isa = PBXGroup; children = ( - DAAA22AA284CF3D100C1975E /* DiscordKit */, 36004E1C283D63E500F0BA73 /* .swiftlint.yml */, DA4A888627C0AF3000720909 /* Swiftcord */, DA4A891727C4B0DF00720909 /* README.md */, @@ -970,7 +968,7 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/SwiftcordApp/DiscordKit"; requirement = { - branch = main; + branch = rearchitect; kind = branch; }; }; diff --git a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4a69a2ee..659e6048 100644 --- a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -9,6 +9,15 @@ "version" : "4.4.2" } }, + { + "identity" : "discordkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftcordApp/DiscordKit", + "state" : { + "branch" : "rearchitect", + "revision" : "cb33e3cd621c84a89e326884aa4843a77c9a7611" + } + }, { "identity" : "lottie-ios", "kind" : "remoteSourceControl", @@ -45,15 +54,6 @@ "version" : "2.1.0" } }, - { - "identity" : "swift-docc-plugin", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-docc-plugin", - "state" : { - "revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6", - "version" : "1.0.0" - } - }, { "identity" : "swiftui-cached-async-image", "kind" : "remoteSourceControl", From a0da240cb8de83f3d52d71c306bf61eb061ff22e Mon Sep 17 00:00:00 2001 From: vinkwok Date: Mon, 6 Jun 2022 18:57:11 +0800 Subject: [PATCH 03/56] Implement a few accessibility settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These aren’t synced as there is no provision in the official client for doing so. --- Swiftcord.xcodeproj/project.pbxproj | 4 +- .../xcshareddata/swiftpm/Package.resolved | 1 + .../SendArrow.imageset/Contents.json | 15 ++++++ .../SendArrow.imageset/send.svg | 1 + .../Views/Message/MessageInputView.swift | 21 +++++--- .../App/AppSettingsAccessibilityView.swift | 54 ++++++++++++++++++- Swiftcord/en.lproj/Localizable.strings | 18 ++++++- Swiftcord/zh-Hans.lproj/Localizable.strings | 18 ++++++- 8 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 Swiftcord/Assets.xcassets/SendArrow.imageset/Contents.json create mode 100644 Swiftcord/Assets.xcassets/SendArrow.imageset/send.svg diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 53c8b1a3..98255849 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -962,8 +962,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/SwiftcordApp/DiscordKit"; requirement = { - kind = revision; - revision = 9a27e869196df8926e1d47af6c73e3135debf51f; + branch = main; + kind = branch; }; }; DA97BA8E2849F9C500059FD7 /* XCRemoteSwiftPackageReference "appcenter-sdk-apple" */ = { diff --git a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved index 678f72b7..6b84ef40 100644 --- a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,6 +14,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/SwiftcordApp/DiscordKit", "state" : { + "branch" : "main", "revision" : "9a27e869196df8926e1d47af6c73e3135debf51f" } }, diff --git a/Swiftcord/Assets.xcassets/SendArrow.imageset/Contents.json b/Swiftcord/Assets.xcassets/SendArrow.imageset/Contents.json new file mode 100644 index 00000000..0f213d11 --- /dev/null +++ b/Swiftcord/Assets.xcassets/SendArrow.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "send.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Swiftcord/Assets.xcassets/SendArrow.imageset/send.svg b/Swiftcord/Assets.xcassets/SendArrow.imageset/send.svg new file mode 100644 index 00000000..6d332588 --- /dev/null +++ b/Swiftcord/Assets.xcassets/SendArrow.imageset/send.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Swiftcord/Views/Message/MessageInputView.swift b/Swiftcord/Views/Message/MessageInputView.swift index 6aad84cf..e82aa372 100644 --- a/Swiftcord/Views/Message/MessageInputView.swift +++ b/Swiftcord/Views/Message/MessageInputView.swift @@ -62,6 +62,8 @@ struct MessageInputView: View { let onSend: (String, [URL]) -> Void let preAttach: (URL) -> Bool + @AppStorage("showSendBtn") private var showSendButton = false + private func send() { guard message.hasContent() || !attachments.isEmpty else { return } onSend(message, attachments) @@ -112,12 +114,19 @@ struct MessageInputView: View { .disableAutocorrection(false) .padding([.top, .bottom], 12) - Button(action: { send() }) { - Image(systemName: "arrow.up").font(.system(size: 20)).opacity(0.75) - } - .keyboardShortcut(.return, modifiers: []) - .buttonStyle(.plain) - .padding(.trailing, 15) + if showSendButton { + let canSend = message.hasContent() || !attachments.isEmpty + Button(action: { send() }) { + Image("SendArrow") + .foregroundColor(.accentColor) + .font(.system(size: 24)) + } + .keyboardShortcut(.return, modifiers: []) + .buttonStyle(.plain) + .padding(.trailing, 15) + .disabled(!canSend) + .animation(.easeOut(duration: 0.2), value: canSend) + } } } .frame(minHeight: 40) diff --git a/Swiftcord/Views/Settings/App/AppSettingsAccessibilityView.swift b/Swiftcord/Views/Settings/App/AppSettingsAccessibilityView.swift index a8b33a19..60dc1445 100644 --- a/Swiftcord/Views/Settings/App/AppSettingsAccessibilityView.swift +++ b/Swiftcord/Views/Settings/App/AppSettingsAccessibilityView.swift @@ -5,15 +5,22 @@ // Created by Vincent Kwok on 6/6/22. // +import AVFoundation import SwiftUI struct AppSettingsAccessibilityView: View { @AppStorage("stickerAlwaysAnim") private var alwaysAnimStickers = true + @AppStorage("showSendBtn") private var showSendButton = false + @AppStorage("ttsRate") private var ttsRate = 0.5 var body: some View { VStack(alignment: .leading, spacing: 16) { Text("settings.app.accessibility").font(.title) - + + Text("settings.app.accessibility.chatInput") + .font(.headline) + .textCase(.uppercase) + .opacity(0.75) VStack(alignment: .leading) { Toggle(isOn: $alwaysAnimStickers) { Text("Always animate stickers").frame(maxWidth: .infinity, alignment: .leading) @@ -21,8 +28,51 @@ struct AppSettingsAccessibilityView: View { .toggleStyle(.switch) .tint(.green) if !alwaysAnimStickers { - Text("settings.app.accessibility.sticker.animInteraction").font(.caption) + Text("settings.animInteraction").font(.caption) + } + } + + Divider() + + Text("settings.app.accessibility.chatInput") + .font(.headline) + .textCase(.uppercase) + .opacity(0.75) + Toggle(isOn: $showSendButton) { + Text("settings.showSendBtn").frame(maxWidth: .infinity, alignment: .leading) + } + .toggleStyle(.switch) + .tint(.green) + + Divider() + + Text("settings.tts.rate").font(.headline).textCase(.uppercase).opacity(0.75) + Button { + let text = "This is what text-to-speech sounds like at the current speed" + + let utterance = AVSpeechUtterance(string: text) + utterance.voice = AVSpeechSynthesisVoice(language: "en-GB") + if ttsRate != 0.5 { utterance.rate = Float(ttsRate) } + + let synthesizer = AVSpeechSynthesizer() + synthesizer.speak(utterance) + } label: { + Label("Preview", systemImage: "play.fill") + } + .buttonStyle(.borderedProminent) + .controlSize(.large) + VStack(alignment: .leading, spacing: 0) { + HStack { + Text("Slower").font(.subheadline).opacity(0.75) + Spacer() + Text("settings.tts.defaultSpeed").font(.subheadline).foregroundColor(.green) + Spacer() + Text("Faster").font(.subheadline).opacity(0.75) } + Slider(value: $ttsRate, in: 0...1, step: 0.1) + Text(String(format: "%.1f", ttsRate)) + .font(.subheadline) + .frame(maxWidth: .infinity, alignment: .trailing) } } } diff --git a/Swiftcord/en.lproj/Localizable.strings b/Swiftcord/en.lproj/Localizable.strings index 5d8353e9..06d24c03 100644 --- a/Swiftcord/en.lproj/Localizable.strings +++ b/Swiftcord/en.lproj/Localizable.strings @@ -52,6 +52,20 @@ "dm.composeMsg.hint %@" = "Message @%@"; /* ====== Settings ====== */ +"settings.showSendBtn" = "Show Send Message button"; + +"settings.animInteraction" = "On the desktop client, stickers will animate on hover or focus. On mobile clients, stickers will animate on long-press."; + +"settings.tts.rate" = "Text-to-speech Rate"; + +"settings.tts.defaultSpeed" = "Default"; + +"settings.tts.slower" = "Slower"; + +"settings.tts.faster" = "Faster"; + +//////////////////////////// + "settings.user.logOut" = "Log Out"; "settings.user.logOut.confirmation" = "Are you sure you want to log out?"; @@ -64,7 +78,9 @@ "settings.app.accessibility" = "Accessibility"; -"settings.app.accessibility.sticker.animInteraction" = "On the desktop client, stickers will animate on hover or focus. On mobile clients, stickers will animate on long-press."; +"settings.app.accessibility.stickers" = "Stickers"; + +"settings.app.accessibility.chatInput" = "Chat Input"; "settings.app.voiceVideo" = "Voice & Video"; diff --git a/Swiftcord/zh-Hans.lproj/Localizable.strings b/Swiftcord/zh-Hans.lproj/Localizable.strings index d7112568..7d1ae41e 100644 --- a/Swiftcord/zh-Hans.lproj/Localizable.strings +++ b/Swiftcord/zh-Hans.lproj/Localizable.strings @@ -100,6 +100,20 @@ "dm.composeMsg.hint %@" = "消息@%@"; /* ====== Settings ====== */ +"settings.showSendBtn" = "显示发送消息按钮"; + +"settings.animInteraction" = "在桌面客户端上,贴纸会在鼠标悬停或聚焦时进入动画状态。在移动客户端上,贴纸会在长按时进入动画状态。"; + +"settings.tts.rate" = "文字转语音速度"; + +"settings.tts.defaultSpeed" = "默认"; + +"settings.tts.slower" = "更慢"; + +"settings.tts.faster" = "更快"; + +//////////////////////////// + "settings.user.logOut" = "登出"; "settings.user.logOut.confirmation" = "您确定您要退出登录吗?"; @@ -112,7 +126,9 @@ "settings.app.accessibility" = "可访问性"; -"settings.app.accessibility.sticker.animInteraction" = "在桌面客户端上,贴纸会在鼠标悬停或聚焦时进入动画状态。在移动客户端上,贴纸会在长按时进入动画状态。"; +"settings.app.accessibility.stickers" = "贴纸"; + +"settings.app.accessibility.chatInput" = "输入消息"; "settings.app.voiceVideo" = "语音和视频"; From b0b7144bbea79bfa90f889621ba65ce88c059e22 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Tue, 7 Jun 2022 21:51:17 +0800 Subject: [PATCH 04/56] Supporting changes for DiscordKit architecture changes --- Swiftcord.xcodeproj/project.pbxproj | 8 ++ .../xcshareddata/swiftpm/Package.resolved | 2 +- Swiftcord/MainScene.swift | 49 ++++++++++ Swiftcord/SwiftcordApp.swift | 17 +++- .../DiscordAPI/Array.Channel+.swift | 2 +- .../Extensions/DiscordAPI/Channel+.swift | 2 +- .../Extensions/DiscordAPI/CurrentUser+.swift | 7 +- .../Utils/Extensions/DiscordAPI/Guild+.swift | 3 +- .../Extensions/DiscordAPI/Message+.swift | 2 +- .../Utils/Extensions/DiscordAPI/User+.swift | 3 +- .../Utils/Extensions/MessagesView+.swift | 5 +- Swiftcord/Utils/Keychain.swift | 90 +++++++++++++++++++ .../MergeStructs/MergePartialMessage.swift | 3 +- Swiftcord/Views/ContentView.swift | 8 +- Swiftcord/Views/Message/AttachmentView.swift | 3 +- Swiftcord/Views/Message/EmbedView.swift | 2 +- Swiftcord/Views/Message/MessageView.swift | 5 +- Swiftcord/Views/Message/MessagesView.swift | 4 +- .../Views/Message/ReferenceMessageView.swift | 2 +- Swiftcord/Views/Message/StickerView.swift | 8 +- Swiftcord/Views/Server/ChannelButton.swift | 2 +- Swiftcord/Views/Server/ChannelList.swift | 2 +- Swiftcord/Views/Server/ServerView.swift | 8 +- Swiftcord/Views/Settings/SettingsView.swift | 2 +- .../User/UserSettingsAccountView.swift | 3 +- .../User/UserSettingsProfileView.swift | 2 +- .../Settings/User/UserSettingsView.swift | 2 +- Swiftcord/Views/User/CurrentUserFooter.swift | 3 +- .../User/Profile/LargeUserProfileView.swift | 2 +- .../User/Profile/MiniUserProfileView.swift | 3 +- .../Views/User/Profile/ProfileBadges.swift | 3 +- Swiftcord/Views/User/UserAvatarView.swift | 4 +- 32 files changed, 209 insertions(+), 52 deletions(-) create mode 100644 Swiftcord/MainScene.swift create mode 100644 Swiftcord/Utils/Keychain.swift diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 61b6cf5a..8b410429 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 3684BB59283C696E005045AE /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 3684BB58283C696E005045AE /* Sparkle */; }; 3684BB5B283C69C5005045AE /* Sparkle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3684BB5A283C69C5005045AE /* Sparkle.swift */; }; 900F6DA1284A1C0C000B6D29 /* GeneratedBuildSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 900F6DA0284A1C0C000B6D29 /* GeneratedBuildSettings.swift */; }; + DA03DA3F284F1E9200257790 /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA03DA3E284F1E9200257790 /* Keychain.swift */; }; DA2384A127CB9714009E15E0 /* Font+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2384A027CB9714009E15E0 /* Font+.swift */; }; DA2384BA27CBC2CE009E15E0 /* GintoBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA2384B827CBC2CE009E15E0 /* GintoBold.otf */; }; DA2384BB27CBC2CE009E15E0 /* GintoMedium.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA2384B927CBC2CE009E15E0 /* GintoMedium.otf */; }; @@ -88,6 +89,7 @@ DAAFB5CC282B879200807B54 /* Double+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5CB282B879200807B54 /* Double+.swift */; }; DAB6C417284B04DB0066E49D /* DebugSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */; }; DAE557FB282D00B6001F4EF1 /* typing-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAE557FA282D00B6001F4EF1 /* typing-animation.json */; }; + DAF68264284F741F00A8BED6 /* MainScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF68263284F741F00A8BED6 /* MainScene.swift */; }; E7AF1C27282FA3ED001F78DF /* Array.Channel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */; }; E7AF1C29282FA3F7001F78DF /* Channel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C28282FA3F7001F78DF /* Channel+.swift */; }; E7AF1C2B282FA400001F78DF /* Guild+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C2A282FA400001F78DF /* Guild+.swift */; }; @@ -104,6 +106,7 @@ 900F6D9F284A1AE6000B6D29 /* Project Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Project Release.xcconfig"; sourceTree = ""; }; 900F6DA0284A1C0C000B6D29 /* GeneratedBuildSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedBuildSettings.swift; sourceTree = ""; }; 90F77AAA284C87E900166BF3 /* AppCenter.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppCenter.xcconfig; sourceTree = ""; }; + DA03DA3E284F1E9200257790 /* Keychain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Keychain.swift; sourceTree = ""; }; DA23843827CB934D009E15E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; DA2384A027CB9714009E15E0 /* Font+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+.swift"; sourceTree = ""; }; DA2384B827CBC2CE009E15E0 /* GintoBold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = GintoBold.otf; sourceTree = ""; }; @@ -180,6 +183,7 @@ DAAFB5CB282B879200807B54 /* Double+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+.swift"; sourceTree = ""; }; DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugSettingsView.swift; sourceTree = ""; }; DAE557FA282D00B6001F4EF1 /* typing-animation.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "typing-animation.json"; sourceTree = ""; }; + DAF68263284F741F00A8BED6 /* MainScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainScene.swift; sourceTree = ""; }; E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array.Channel+.swift"; sourceTree = ""; }; E7AF1C28282FA3F7001F78DF /* Channel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Channel+.swift"; sourceTree = ""; }; E7AF1C2A282FA400001F78DF /* Guild+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Guild+.swift"; sourceTree = ""; }; @@ -307,6 +311,7 @@ DA7720CE283F182700D3C335 /* Commands */, DA4A88DC27C3272500720909 /* Utils */, DA32EF6327CB770E00A9ED72 /* DataModels */, + DAF68263284F741F00A8BED6 /* MainScene.swift */, DA4A888727C0AF3000720909 /* SwiftcordApp.swift */, DA2802782808337B00B14E5C /* AppDelegate.swift */, DA4A889027C0AF3200720909 /* Persistence.swift */, @@ -334,6 +339,7 @@ DA54D5822846496900B11857 /* Animation */, DA520AE327D76BF8009FD740 /* Extensions */, DA520AC127D37863009FD740 /* MergeStructs */, + DA03DA3E284F1E9200257790 /* Keychain.swift */, DA4A889B27C0B23C00720909 /* WebView.swift */, DAAFB5C6282AB56B00807B54 /* AudioCenterManager.swift */, 3684BB5A283C69C5005045AE /* Sparkle.swift */, @@ -651,6 +657,7 @@ DA54D57F28460F3A00B11857 /* ReferenceMessageView.swift in Sources */, DA32EF2427C6249000A9ED72 /* MessagesView.swift in Sources */, DA97BA8C2849C0FA00059FD7 /* Cache.swift in Sources */, + DA03DA3F284F1E9200257790 /* Keychain.swift in Sources */, E7AF1C27282FA3ED001F78DF /* Array.Channel+.swift in Sources */, DA520AC327D37873009FD740 /* MergePartialMessage.swift in Sources */, E7AF1C36282FC2E8001F78DF /* NSTextView+.swift in Sources */, @@ -702,6 +709,7 @@ DA32EF2827C633FE00A9ED72 /* UserAvatarView.swift in Sources */, DA585C9927E1F6AC00FA4EE0 /* View+.swift in Sources */, DA32EF4A27C8BE8F00A9ED72 /* Color+.swift in Sources */, + DAF68264284F741F00A8BED6 /* MainScene.swift in Sources */, DA7720D0283F184100D3C335 /* NavigationCommands.swift in Sources */, DAAFB5BC282A570D00807B54 /* CircularProgressView.swift in Sources */, 3684BB5B283C69C5005045AE /* Sparkle.swift in Sources */, diff --git a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved index 659e6048..9ed5de3a 100644 --- a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/SwiftcordApp/DiscordKit", "state" : { "branch" : "rearchitect", - "revision" : "cb33e3cd621c84a89e326884aa4843a77c9a7611" + "revision" : "f561dbdd097e93b79d14536f76808d732620243f" } }, { diff --git a/Swiftcord/MainScene.swift b/Swiftcord/MainScene.swift new file mode 100644 index 00000000..601e52b8 --- /dev/null +++ b/Swiftcord/MainScene.swift @@ -0,0 +1,49 @@ +// +// MainScene.swift +// Swiftcord +// +// Created by Vincent Kwok on 7/6/22. +// + +import SwiftUI + +struct MainScene: Scene { + let token: String + + @StateObject var updaterViewModel = UpdaterViewModel() + @EnvironmentObject var state: UIState + + @AppStorage("theme") private var selectedTheme = "system" + + var body: some Scene { + WindowGroup { + ContentView() + .overlay(LoadingView()) + //.environmentObject(gateway) + .environmentObject(state) + // .environment(\.locale, .init(identifier: "zh-Hans")) + // .environment(\.managedObjectContext, persistenceController.container.viewContext) + .preferredColorScheme(selectedTheme == "dark" + ? .dark + : (selectedTheme == "light" ? .light : nil)) + } + .commands { + CommandGroup(after: .appInfo) { + CheckForUpdatesView(updaterViewModel: updaterViewModel) + } + + SidebarCommands() + NavigationCommands() + } + + Settings { + SettingsView() + //.environmentObject(gateway) + .environmentObject(state) + .preferredColorScheme(selectedTheme == "dark" + ? .dark + : (selectedTheme == "light" ? .light : nil)) + // .environment(\.locale, .init(identifier: "zh-Hans")) + } + } +} diff --git a/Swiftcord/SwiftcordApp.swift b/Swiftcord/SwiftcordApp.swift index 0befcba6..8d38aec4 100644 --- a/Swiftcord/SwiftcordApp.swift +++ b/Swiftcord/SwiftcordApp.swift @@ -6,6 +6,7 @@ // import DiscordKit +import DiscordKitCore import SwiftUI // There's probably a better place to put global constants @@ -13,11 +14,13 @@ let appName = Bundle.main.infoDictionary?[kCFBundleNameKey as String] as? String @main struct SwiftcordApp: App { - @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate - let persistenceController = PersistenceController.shared - @StateObject var updaterViewModel = UpdaterViewModel() + static private let tokenKeychainKey = "authToken" + // @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate + // let persistenceController = PersistenceController.shared + @StateObject var updaterViewModel = UpdaterViewModel() @StateObject private var gateway = DiscordGateway() + @StateObject private var restAPI = DiscordREST() @StateObject private var state = UIState() @AppStorage("theme") private var selectedTheme = "system" @@ -28,11 +31,17 @@ struct SwiftcordApp: App { .overlay(LoadingView()) .environmentObject(gateway) .environmentObject(state) + .environmentObject(restAPI) // .environment(\.locale, .init(identifier: "zh-Hans")) - .environment(\.managedObjectContext, persistenceController.container.viewContext) + // .environment(\.managedObjectContext, persistenceController.container.viewContext) .preferredColorScheme(selectedTheme == "dark" ? .dark : (selectedTheme == "light" ? .light : nil)) + .onAppear { + guard let token = Keychain.load(key: SwiftcordApp.tokenKeychainKey) else { return } + gateway.connect(token: token) + restAPI.setToken(token: token) + } } .commands { CommandGroup(after: .appInfo) { diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/Array.Channel+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/Array.Channel+.swift index 6389df57..c2abd7e5 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/Array.Channel+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/Array.Channel+.swift @@ -5,7 +5,7 @@ // Created by royal on 14/05/2022. // -import DiscordKitCore +import DiscordKitCommon extension Array where Element == Channel { func discordSorted() -> Self { diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/Channel+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/Channel+.swift index 400461b1..7adc1e1d 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/Channel+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/Channel+.swift @@ -5,7 +5,7 @@ // Created by royal on 14/05/2022. // -import DiscordKitCore +import DiscordKitCommon extension Channel { func label(_ users: [Snowflake: User] = [:]) -> String? { diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/CurrentUser+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/CurrentUser+.swift index e6be200f..465673d2 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/CurrentUser+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/CurrentUser+.swift @@ -6,15 +6,14 @@ // import Foundation -import DiscordKit -import DiscordKitCore +import DiscordKitCommon extension CurrentUser { func avatarURL(size: Int = 160) -> URL { if let avatar = avatar { - return URL(string: "\(GatewayConfig.default.cdnURL)avatars/\(self.id)/\(avatar).webp?size=\(size)")! + return URL(string: "\(DiscordKitConfig.default.cdnURL)avatars/\(self.id)/\(avatar).webp?size=\(size)")! } else { - return URL(string: "\(GatewayConfig.default.cdnURL)embed/avatars/\((Int(self.discriminator) ?? 0) % 5).png")! + return URL(string: "\(DiscordKitConfig.default.cdnURL)embed/avatars/\((Int(self.discriminator) ?? 0) % 5).png")! } } } diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/Guild+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/Guild+.swift index b8d069d1..eb4eede5 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/Guild+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/Guild+.swift @@ -5,8 +5,7 @@ // Created by royal on 14/05/2022. // -import DiscordKit -import DiscordKitCore +import DiscordKitCommon extension Guild { var isDMChannel: Bool { id == "@me" } diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/Message+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/Message+.swift index 6a4037c2..75dc6999 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/Message+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/Message+.swift @@ -6,7 +6,7 @@ // import Foundation -import DiscordKitCore +import DiscordKitCommon extension Message { func messageIsShrunk(prev: Message) -> Bool { diff --git a/Swiftcord/Utils/Extensions/DiscordAPI/User+.swift b/Swiftcord/Utils/Extensions/DiscordAPI/User+.swift index 95aa360b..e55566c4 100644 --- a/Swiftcord/Utils/Extensions/DiscordAPI/User+.swift +++ b/Swiftcord/Utils/Extensions/DiscordAPI/User+.swift @@ -6,8 +6,7 @@ // import Foundation -import DiscordKit -import DiscordKitCore +import DiscordKitCommon extension User { func avatarURL(size: Int = 160) -> URL { diff --git a/Swiftcord/Utils/Extensions/MessagesView+.swift b/Swiftcord/Utils/Extensions/MessagesView+.swift index a81a9a2a..ce8a3fef 100644 --- a/Swiftcord/Utils/Extensions/MessagesView+.swift +++ b/Swiftcord/Utils/Extensions/MessagesView+.swift @@ -7,6 +7,7 @@ import Foundation import DiscordKit +import DiscordKitCommon import DiscordKitCore extension MessagesView { @@ -23,7 +24,7 @@ extension MessagesView { fetchMessagesTask = Task { let lastMsg = messages.isEmpty ? nil : messages[messages.count - 1].id - guard let newMessages = await DiscordAPI.getChannelMsgs( + guard let newMessages = await restAPI.getChannelMsgs( id: channel.id, before: lastMsg ) else { @@ -56,7 +57,7 @@ extension MessagesView { newMessage = "" showingInfoBar = false Task { - guard (await DiscordAPI.createChannelMsg( + guard (await restAPI.createChannelMsg( message: NewMessage( content: message, attachments: attachments.isEmpty ? nil : attachments.enumerated() diff --git a/Swiftcord/Utils/Keychain.swift b/Swiftcord/Utils/Keychain.swift new file mode 100644 index 00000000..4ba23e3a --- /dev/null +++ b/Swiftcord/Utils/Keychain.swift @@ -0,0 +1,90 @@ +// +// Keychain.swift +// DiscordKitCommon +// +// Created by Vincent Kwok on 21/2/22. +// +// Adapted from: https://stackoverflow.com/a/37539998 (actually had a Swift 5 example) + +import Foundation +import Security + +public class Keychain { + static let tag = Bundle.main.bundleIdentifier!.data(using: .utf8)! + + @discardableResult + public class func save(key: String, data: String) -> OSStatus { + return save(key: key, data: data.data(using: .utf8)!) + } + + @discardableResult + public class func save(key: String, data: Data) -> OSStatus { + let query = [ + kSecClass as String: kSecClassGenericPassword as String, + kSecAttrAccount as String: "\(Bundle.main.bundleIdentifier!).\(key)", + kSecAttrApplicationTag as String: tag, + kSecValueData as String: data + ] as [String: Any] + + SecItemDelete(query as CFDictionary) + + return SecItemAdd(query as CFDictionary, nil) + } + + @discardableResult + public class func remove(key: String) -> OSStatus { + let query = [ + kSecClass as String: kSecClassGenericPassword as String, + kSecAttrAccount as String: "\(Bundle.main.bundleIdentifier!).\(key)", + kSecAttrApplicationTag as String: tag, + kSecMatchLimit as String: kSecMatchLimitOne + ] as [String: Any] + + return SecItemDelete(query as CFDictionary) + } + + public class func load(key: String) -> String? { + guard let data: Data = loadData(key: key) else { return nil } + return String(data: data, encoding: .utf8) + } + + public class func loadData(key: String) -> Data? { + let query = [ + kSecClass as String: kSecClassGenericPassword, + kSecAttrAccount as String: "\(Bundle.main.bundleIdentifier!).\(key)", + kSecReturnData as String: kCFBooleanTrue!, + kSecAttrApplicationTag as String: tag, + kSecMatchLimit as String: kSecMatchLimitOne + ] as [String: Any] + + var dataTypeRef: AnyObject? + + let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataTypeRef) + + guard status == noErr else { return nil } + return dataTypeRef as? Data + } + + public class func createUniqueID() -> String { + let uuid: CFUUID = CFUUIDCreate(nil) + let cfStr: CFString = CFUUIDCreateString(nil, uuid) + + let swiftString: String = cfStr as String + return swiftString + } +} + +public extension Data { + init(from value: T) { + var value = value + var d = Data() + withUnsafePointer(to: &value, { (ptr: UnsafePointer) -> Void in + d = Data( buffer: UnsafeBufferPointer(start: ptr, count: 1)) + }) + self.init(d) + } + + func to(type: T.Type) -> T { + return self.withUnsafeBytes { $0.load(as: T.self) } + } +} diff --git a/Swiftcord/Utils/MergeStructs/MergePartialMessage.swift b/Swiftcord/Utils/MergeStructs/MergePartialMessage.swift index f65a3a5a..982e695a 100644 --- a/Swiftcord/Utils/MergeStructs/MergePartialMessage.swift +++ b/Swiftcord/Utils/MergeStructs/MergePartialMessage.swift @@ -8,8 +8,7 @@ // Fields from PartialMessage are favored import Foundation -import DiscordKit -import DiscordKitCore +import DiscordKitCommon extension Message { mutating func mergeWithPartialMsg(_ partial: PartialMessage) { diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index 66bbd4a1..89d006f9 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -166,7 +166,7 @@ struct ContentView: View { if let token = token { state.attemptLogin = false Keychain.save(key: "authToken", data: token) - gateway.connect() // Reconnect to the socket + gateway.connect(token: token) // Reconnect to the socket } }) .onAppear { @@ -175,7 +175,7 @@ struct ContentView: View { _ = gateway.onAuthFailure.addHandler { state.attemptLogin = true state.loadingState = .initial - log.debug("User isn't logged in, attempting login") + log.debug("Attempting login") } _ = gateway.onEvent.addHandler { (evt, _) in switch evt { @@ -183,7 +183,7 @@ struct ContentView: View { state.loadingState = .gatewayConn fallthrough case .resumed: - gateway.socket.send(op: .voiceStateUpdate, data: GatewayVoiceStateUpdate( + gateway.send(op: .voiceStateUpdate, data: GatewayVoiceStateUpdate( guild_id: nil, channel_id: nil, self_mute: state.selfMute, @@ -193,7 +193,7 @@ struct ContentView: View { default: break } } - _ = gateway.socket.onSessionInvalid.addHandler { state.loadingState = .initial } + _ = gateway.socket?.onSessionInvalid.addHandler { state.loadingState = .initial } } } diff --git a/Swiftcord/Views/Message/AttachmentView.swift b/Swiftcord/Views/Message/AttachmentView.swift index 0174b9ed..6b0e18e0 100644 --- a/Swiftcord/Views/Message/AttachmentView.swift +++ b/Swiftcord/Views/Message/AttachmentView.swift @@ -10,8 +10,7 @@ import SwiftUI import AVKit import CachedAsyncImage import QuickLook -import DiscordKit -import DiscordKitCore +import DiscordKitCommon struct AttachmentError: View { let height: Int diff --git a/Swiftcord/Views/Message/EmbedView.swift b/Swiftcord/Views/Message/EmbedView.swift index baa645b5..97c8ef2c 100644 --- a/Swiftcord/Views/Message/EmbedView.swift +++ b/Swiftcord/Views/Message/EmbedView.swift @@ -7,7 +7,7 @@ import SwiftUI import CachedAsyncImage -import DiscordKitCore +import DiscordKitCommon struct EmbedView: View { let embed: Embed diff --git a/Swiftcord/Views/Message/MessageView.swift b/Swiftcord/Views/Message/MessageView.swift index d9555bf9..09bfd146 100644 --- a/Swiftcord/Views/Message/MessageView.swift +++ b/Swiftcord/Views/Message/MessageView.swift @@ -8,7 +8,7 @@ import SwiftUI import CachedAsyncImage -import DiscordKit +import DiscordKitCommon import DiscordKitCore struct NonUserBadge: View { @@ -49,6 +49,7 @@ struct MessageView: View { @State private var loadQuotedMsgErr = false @EnvironmentObject var serverCtx: ServerContext + @EnvironmentObject var restAPI: DiscordREST public static let supportedTypes: [MessageType] = [.defaultMsg, .reply, .guildMemberJoin] @@ -241,7 +242,7 @@ private extension MessageView { func deleteMessage() { Task { - await DiscordAPI.deleteMsg(id: message.channel_id, msgID: message.id) + await restAPI.deleteMsg(id: message.channel_id, msgID: message.id) } } diff --git a/Swiftcord/Views/Message/MessagesView.swift b/Swiftcord/Views/Message/MessagesView.swift index 8c74c0eb..f584f380 100644 --- a/Swiftcord/Views/Message/MessagesView.swift +++ b/Swiftcord/Views/Message/MessagesView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import DiscordKitCommon import DiscordKit import DiscordKitCore import CachedAsyncImage @@ -101,6 +102,7 @@ struct MessagesView: View { @State private var highlightMsg: Snowflake? @EnvironmentObject var gateway: DiscordGateway + @EnvironmentObject var restAPI: DiscordREST @EnvironmentObject var state: UIState @EnvironmentObject var ctx: ServerContext @@ -209,7 +211,7 @@ struct MessagesView: View { // Send typing start msg once every 8s while typing lastSentTyping = Date() Task { - _ = await DiscordAPI.typingStart(id: ctx.channel!.id) + _ = await restAPI.typingStart(id: ctx.channel!.id) } } } diff --git a/Swiftcord/Views/Message/ReferenceMessageView.swift b/Swiftcord/Views/Message/ReferenceMessageView.swift index 6df018f8..4bdc17f1 100644 --- a/Swiftcord/Views/Message/ReferenceMessageView.swift +++ b/Swiftcord/Views/Message/ReferenceMessageView.swift @@ -6,8 +6,8 @@ // import SwiftUI -import DiscordKit import DiscordKitCore +import DiscordKitCommon import CachedAsyncImage struct ReferenceMessageView: View { diff --git a/Swiftcord/Views/Message/StickerView.swift b/Swiftcord/Views/Message/StickerView.swift index dd31049c..6506f82d 100644 --- a/Swiftcord/Views/Message/StickerView.swift +++ b/Swiftcord/Views/Message/StickerView.swift @@ -7,9 +7,9 @@ import SwiftUI import Lottie -import DiscordKit -import DiscordKitCore +import DiscordKitCommon import CachedAsyncImage +import DiscordKitCore struct StickerLoadingView: View { let size: Double @@ -102,6 +102,8 @@ struct StickerView: View { @State private var error = false @State private var fullSticker: Sticker? @State private var packPresenting = false + + @EnvironmentObject var restAPI: DiscordREST private func openPopoverEvt() { AnalyticsWrapper.event(type: .openPopout, properties: [ @@ -155,7 +157,7 @@ struct StickerView: View { .onHover { isHovered in play = isHovered } .onTapGesture { if fullSticker == nil { Task { - fullSticker = await DiscordAPI.getSticker(id: sticker.id) + fullSticker = await restAPI.getSticker(id: sticker.id) openPopoverEvt() }} else { openPopoverEvt() diff --git a/Swiftcord/Views/Server/ChannelButton.swift b/Swiftcord/Views/Server/ChannelButton.swift index 95c32069..a14faba7 100644 --- a/Swiftcord/Views/Server/ChannelButton.swift +++ b/Swiftcord/Views/Server/ChannelButton.swift @@ -6,8 +6,8 @@ // import SwiftUI +import DiscordKitCommon import DiscordKit -import DiscordKitCore import CachedAsyncImage struct ChannelButton: View { diff --git a/Swiftcord/Views/Server/ChannelList.swift b/Swiftcord/Views/Server/ChannelList.swift index c96d2b8b..a9a44e20 100644 --- a/Swiftcord/Views/Server/ChannelList.swift +++ b/Swiftcord/Views/Server/ChannelList.swift @@ -6,8 +6,8 @@ // import SwiftUI +import DiscordKitCommon import DiscordKit -import DiscordKitCore struct ChannelList: View { let channels: [Channel] diff --git a/Swiftcord/Views/Server/ServerView.swift b/Swiftcord/Views/Server/ServerView.swift index 59a0e530..00864d00 100644 --- a/Swiftcord/Views/Server/ServerView.swift +++ b/Swiftcord/Views/Server/ServerView.swift @@ -6,8 +6,9 @@ // import SwiftUI -import DiscordKitCore import DiscordKit +import DiscordKitCommon +import DiscordKitCore class ServerContext: ObservableObject { @Published public var channel: Channel? @@ -23,6 +24,7 @@ struct ServerView: View { @EnvironmentObject var state: UIState @EnvironmentObject var gateway: DiscordGateway + @EnvironmentObject var restAPI: DiscordREST @EnvironmentObject var audioManager: AudioCenterManager @StateObject private var serverCtx = ServerContext() @@ -63,13 +65,13 @@ struct ServerView: View { ]) // Subscribe to typing events - gateway.socket.send( + gateway.send( op: .subscribeGuildEvents, data: SubscribeGuildEvts(guild_id: guild.id, typing: true) ) // Retrieve guild roles to update context Task { - guard let newRoles = await DiscordAPI.getGuildRoles(id: guild.id) else { return } + guard let newRoles = await restAPI.getGuildRoles(id: guild.id) else { return } serverCtx.roles = newRoles } } diff --git a/Swiftcord/Views/Settings/SettingsView.swift b/Swiftcord/Views/Settings/SettingsView.swift index d531155b..7f0697a8 100644 --- a/Swiftcord/Views/Settings/SettingsView.swift +++ b/Swiftcord/Views/Settings/SettingsView.swift @@ -7,7 +7,7 @@ import SwiftUI import DiscordKit -import DiscordKitCore +import DiscordKitCommon struct SettingsView: View { @EnvironmentObject var gateway: DiscordGateway diff --git a/Swiftcord/Views/Settings/User/UserSettingsAccountView.swift b/Swiftcord/Views/Settings/User/UserSettingsAccountView.swift index 0468e7ac..eb63d4f6 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsAccountView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsAccountView.swift @@ -6,8 +6,7 @@ // import SwiftUI -import DiscordKit -import DiscordKitCore +import DiscordKitCommon struct UserSettingsAccountView: View { let user: CurrentUser diff --git a/Swiftcord/Views/Settings/User/UserSettingsProfileView.swift b/Swiftcord/Views/Settings/User/UserSettingsProfileView.swift index 47bf87ab..b8f699f7 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsProfileView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsProfileView.swift @@ -6,7 +6,7 @@ // import SwiftUI -import DiscordKitCore +import DiscordKitCommon struct UserSettingsProfileView: View { let user: CurrentUser diff --git a/Swiftcord/Views/Settings/User/UserSettingsView.swift b/Swiftcord/Views/Settings/User/UserSettingsView.swift index 75805889..05629baa 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsView.swift @@ -7,7 +7,7 @@ import SwiftUI import DiscordKit -import DiscordKitCore +import DiscordKitCommon struct UserSettingsView: View { let user: CurrentUser diff --git a/Swiftcord/Views/User/CurrentUserFooter.swift b/Swiftcord/Views/User/CurrentUserFooter.swift index 6de744f0..7c622c3b 100644 --- a/Swiftcord/Views/User/CurrentUserFooter.swift +++ b/Swiftcord/Views/User/CurrentUserFooter.swift @@ -8,8 +8,7 @@ import SwiftUI import CachedAsyncImage -import DiscordKit -import DiscordKitCore +import DiscordKitCommon struct CurrentUserFooter: View { let user: CurrentUser diff --git a/Swiftcord/Views/User/Profile/LargeUserProfileView.swift b/Swiftcord/Views/User/Profile/LargeUserProfileView.swift index 25df2029..c0b2252a 100644 --- a/Swiftcord/Views/User/Profile/LargeUserProfileView.swift +++ b/Swiftcord/Views/User/Profile/LargeUserProfileView.swift @@ -7,7 +7,7 @@ import SwiftUI import CachedAsyncImage -import DiscordKitCore +import DiscordKitCommon struct LargeUserProfile: View { let user: CurrentUser diff --git a/Swiftcord/Views/User/Profile/MiniUserProfileView.swift b/Swiftcord/Views/User/Profile/MiniUserProfileView.swift index d794c2ad..a4ae6e77 100644 --- a/Swiftcord/Views/User/Profile/MiniUserProfileView.swift +++ b/Swiftcord/Views/User/Profile/MiniUserProfileView.swift @@ -6,8 +6,7 @@ // import SwiftUI -import DiscordKit -import DiscordKitCore +import DiscordKitCommon import CachedAsyncImage struct MiniUserProfileView: View { diff --git a/Swiftcord/Views/User/Profile/ProfileBadges.swift b/Swiftcord/Views/User/Profile/ProfileBadges.swift index a37a1fa9..846d0c9e 100644 --- a/Swiftcord/Views/User/Profile/ProfileBadges.swift +++ b/Swiftcord/Views/User/Profile/ProfileBadges.swift @@ -5,8 +5,7 @@ // Created by Vincent Kwok on 30/5/22. // -import DiscordKit -import DiscordKitCore +import DiscordKitCommon import SwiftUI struct ProfileBadges: View, Equatable { diff --git a/Swiftcord/Views/User/UserAvatarView.swift b/Swiftcord/Views/User/UserAvatarView.swift index 36f36d96..3eb5545f 100644 --- a/Swiftcord/Views/User/UserAvatarView.swift +++ b/Swiftcord/Views/User/UserAvatarView.swift @@ -7,6 +7,7 @@ import SwiftUI import CachedAsyncImage +import DiscordKitCommon import DiscordKitCore import DiscordKit @@ -22,6 +23,7 @@ struct UserAvatarView: View, Equatable { @EnvironmentObject var ctx: ServerContext @EnvironmentObject var gateway: DiscordGateway + @EnvironmentObject var restAPI: DiscordREST static private let profileCache = Cache() @@ -60,7 +62,7 @@ struct UserAvatarView: View, Equatable { webhookID == nil, guildID != "@me" || profile?.user == nil { Task { - guard let loadedProfile = await DiscordAPI.getProfile( + guard let loadedProfile = await restAPI.getProfile( user: user.id, guildID: guildID == "@me" ? nil : guildID ) else { // Profile is still nil: fetching failed From 9b21f4f75c69a99b116afc165c10b55c972a7efd Mon Sep 17 00:00:00 2001 From: vinkwok Date: Wed, 8 Jun 2022 10:42:08 +0800 Subject: [PATCH 05/56] Fix logging in with new DiscordKit architecture --- Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- Swiftcord/SwiftcordApp.swift | 5 ++++- Swiftcord/Views/ContentView.swift | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9ed5de3a..d3603ea7 100644 --- a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/SwiftcordApp/DiscordKit", "state" : { "branch" : "rearchitect", - "revision" : "f561dbdd097e93b79d14536f76808d732620243f" + "revision" : "674cfdc99c02c78078c3c6a16ff028ab5968a9f2" } }, { diff --git a/Swiftcord/SwiftcordApp.swift b/Swiftcord/SwiftcordApp.swift index 8d38aec4..c623ad7b 100644 --- a/Swiftcord/SwiftcordApp.swift +++ b/Swiftcord/SwiftcordApp.swift @@ -38,7 +38,10 @@ struct SwiftcordApp: App { ? .dark : (selectedTheme == "light" ? .light : nil)) .onAppear { - guard let token = Keychain.load(key: SwiftcordApp.tokenKeychainKey) else { return } + guard let token = Keychain.load(key: SwiftcordApp.tokenKeychainKey) else { + state.attemptLogin = true + return + } gateway.connect(token: token) restAPI.setToken(token: token) } diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index 89d006f9..6b8fc800 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -34,6 +34,7 @@ struct ContentView: View { @StateObject private var audioManager = AudioCenterManager() @EnvironmentObject var gateway: DiscordGateway + @EnvironmentObject var restAPI: DiscordREST @EnvironmentObject var state: UIState private let log = Logger(category: "ContentView") @@ -166,7 +167,8 @@ struct ContentView: View { if let token = token { state.attemptLogin = false Keychain.save(key: "authToken", data: token) - gateway.connect(token: token) // Reconnect to the socket + gateway.connect(token: token) // Reconnect to the socket with the new token + restAPI.setToken(token: token) } }) .onAppear { From 23ed1b379eb1aa4ffeba46f9a35598b362d901e7 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Wed, 8 Jun 2022 11:53:49 +0800 Subject: [PATCH 06/56] Update appcast.xml with new release (0.4.1) --- appcast.xml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/appcast.xml b/appcast.xml index 3528de70..f37cd3de 100644 --- a/appcast.xml +++ b/appcast.xml @@ -2,6 +2,18 @@ Swiftcord + + 0.4.1 + Wed, 08 Jun 2022 10:39:11 +0800 + 8 + 0.4.1 + 12.0 + + https://github.com/SwiftcordApp/Swiftcord/releases + + + + 0.4.0 Thu, 26 May 2022 13:08:54 +0800 @@ -9,7 +21,6 @@ 0.4.0 12.0 - https://github.com/SwiftcordApp/Swiftcord/releases/tag/v0.4.0 https://github.com/SwiftcordApp/Swiftcord/releases From 3204bfcf284de0218fae61ece5ca15242cd098ca Mon Sep 17 00:00:00 2001 From: vinkwok Date: Fri, 10 Jun 2022 11:20:05 +0800 Subject: [PATCH 07/56] Replace hardcoded keychain key with constant Fixed some swiftlint warnings --- Swiftcord.xcodeproj/project.pbxproj | 4 -- .../xcshareddata/swiftpm/Package.resolved | 2 +- Swiftcord/MainScene.swift | 49 ------------------- Swiftcord/SwiftcordApp.swift | 2 +- Swiftcord/Utils/Keychain.swift | 6 +-- Swiftcord/Views/ContentView.swift | 2 +- Swiftcord/Views/Message/StickerView.swift | 2 +- 7 files changed, 7 insertions(+), 60 deletions(-) delete mode 100644 Swiftcord/MainScene.swift diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 8b410429..50203e24 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -89,7 +89,6 @@ DAAFB5CC282B879200807B54 /* Double+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5CB282B879200807B54 /* Double+.swift */; }; DAB6C417284B04DB0066E49D /* DebugSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */; }; DAE557FB282D00B6001F4EF1 /* typing-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAE557FA282D00B6001F4EF1 /* typing-animation.json */; }; - DAF68264284F741F00A8BED6 /* MainScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF68263284F741F00A8BED6 /* MainScene.swift */; }; E7AF1C27282FA3ED001F78DF /* Array.Channel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */; }; E7AF1C29282FA3F7001F78DF /* Channel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C28282FA3F7001F78DF /* Channel+.swift */; }; E7AF1C2B282FA400001F78DF /* Guild+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C2A282FA400001F78DF /* Guild+.swift */; }; @@ -183,7 +182,6 @@ DAAFB5CB282B879200807B54 /* Double+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+.swift"; sourceTree = ""; }; DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugSettingsView.swift; sourceTree = ""; }; DAE557FA282D00B6001F4EF1 /* typing-animation.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "typing-animation.json"; sourceTree = ""; }; - DAF68263284F741F00A8BED6 /* MainScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainScene.swift; sourceTree = ""; }; E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array.Channel+.swift"; sourceTree = ""; }; E7AF1C28282FA3F7001F78DF /* Channel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Channel+.swift"; sourceTree = ""; }; E7AF1C2A282FA400001F78DF /* Guild+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Guild+.swift"; sourceTree = ""; }; @@ -311,7 +309,6 @@ DA7720CE283F182700D3C335 /* Commands */, DA4A88DC27C3272500720909 /* Utils */, DA32EF6327CB770E00A9ED72 /* DataModels */, - DAF68263284F741F00A8BED6 /* MainScene.swift */, DA4A888727C0AF3000720909 /* SwiftcordApp.swift */, DA2802782808337B00B14E5C /* AppDelegate.swift */, DA4A889027C0AF3200720909 /* Persistence.swift */, @@ -709,7 +706,6 @@ DA32EF2827C633FE00A9ED72 /* UserAvatarView.swift in Sources */, DA585C9927E1F6AC00FA4EE0 /* View+.swift in Sources */, DA32EF4A27C8BE8F00A9ED72 /* Color+.swift in Sources */, - DAF68264284F741F00A8BED6 /* MainScene.swift in Sources */, DA7720D0283F184100D3C335 /* NavigationCommands.swift in Sources */, DAAFB5BC282A570D00807B54 /* CircularProgressView.swift in Sources */, 3684BB5B283C69C5005045AE /* Sparkle.swift in Sources */, diff --git a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved index d3603ea7..104d3cf1 100644 --- a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/SwiftcordApp/DiscordKit", "state" : { "branch" : "rearchitect", - "revision" : "674cfdc99c02c78078c3c6a16ff028ab5968a9f2" + "revision" : "c0334e29bcf5548dfe54b3d0a7b0df9af27c86eb" } }, { diff --git a/Swiftcord/MainScene.swift b/Swiftcord/MainScene.swift deleted file mode 100644 index 601e52b8..00000000 --- a/Swiftcord/MainScene.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// MainScene.swift -// Swiftcord -// -// Created by Vincent Kwok on 7/6/22. -// - -import SwiftUI - -struct MainScene: Scene { - let token: String - - @StateObject var updaterViewModel = UpdaterViewModel() - @EnvironmentObject var state: UIState - - @AppStorage("theme") private var selectedTheme = "system" - - var body: some Scene { - WindowGroup { - ContentView() - .overlay(LoadingView()) - //.environmentObject(gateway) - .environmentObject(state) - // .environment(\.locale, .init(identifier: "zh-Hans")) - // .environment(\.managedObjectContext, persistenceController.container.viewContext) - .preferredColorScheme(selectedTheme == "dark" - ? .dark - : (selectedTheme == "light" ? .light : nil)) - } - .commands { - CommandGroup(after: .appInfo) { - CheckForUpdatesView(updaterViewModel: updaterViewModel) - } - - SidebarCommands() - NavigationCommands() - } - - Settings { - SettingsView() - //.environmentObject(gateway) - .environmentObject(state) - .preferredColorScheme(selectedTheme == "dark" - ? .dark - : (selectedTheme == "light" ? .light : nil)) - // .environment(\.locale, .init(identifier: "zh-Hans")) - } - } -} diff --git a/Swiftcord/SwiftcordApp.swift b/Swiftcord/SwiftcordApp.swift index c623ad7b..ee0ad243 100644 --- a/Swiftcord/SwiftcordApp.swift +++ b/Swiftcord/SwiftcordApp.swift @@ -14,7 +14,7 @@ let appName = Bundle.main.infoDictionary?[kCFBundleNameKey as String] as? String @main struct SwiftcordApp: App { - static private let tokenKeychainKey = "authToken" + static internal let tokenKeychainKey = "authToken" // @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate // let persistenceController = PersistenceController.shared diff --git a/Swiftcord/Utils/Keychain.swift b/Swiftcord/Utils/Keychain.swift index 4ba23e3a..b0f4b2fe 100644 --- a/Swiftcord/Utils/Keychain.swift +++ b/Swiftcord/Utils/Keychain.swift @@ -77,11 +77,11 @@ public class Keychain { public extension Data { init(from value: T) { var value = value - var d = Data() + var tempData = Data() withUnsafePointer(to: &value, { (ptr: UnsafePointer) -> Void in - d = Data( buffer: UnsafeBufferPointer(start: ptr, count: 1)) + tempData = Data( buffer: UnsafeBufferPointer(start: ptr, count: 1)) }) - self.init(d) + self.init(tempData) } func to(type: T.Type) -> T { diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index 6b8fc800..e6b8c28c 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -166,7 +166,7 @@ struct ContentView: View { .onChange(of: loginWVModel.token, perform: { token in if let token = token { state.attemptLogin = false - Keychain.save(key: "authToken", data: token) + Keychain.save(key: SwiftcordApp.tokenKeychainKey, data: token) gateway.connect(token: token) // Reconnect to the socket with the new token restAPI.setToken(token: token) } diff --git a/Swiftcord/Views/Message/StickerView.swift b/Swiftcord/Views/Message/StickerView.swift index 6506f82d..8e50da41 100644 --- a/Swiftcord/Views/Message/StickerView.swift +++ b/Swiftcord/Views/Message/StickerView.swift @@ -102,7 +102,7 @@ struct StickerView: View { @State private var error = false @State private var fullSticker: Sticker? @State private var packPresenting = false - + @EnvironmentObject var restAPI: DiscordREST private func openPopoverEvt() { From cbc90881c756d1806dd9dcd5d994d59a29095d8d Mon Sep 17 00:00:00 2001 From: Liam <101684827+SkiingIsFun123@users.noreply.github.com> Date: Mon, 13 Jun 2022 22:33:30 -0700 Subject: [PATCH 08/56] Update README.md --- README.md | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 0983f213..6ac7816b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ me to continue developing it** Swiftcord was created to offer a Discord-like UI and experience while having the performance and memory benefits of native apps. The idea started brewing when I was tight on RAM, then noticed Discord using 600+MB of RAM. -I then realised that that was the perfect opportunity to explore SwiftUI, +I then realized that that was the perfect opportunity to explore SwiftUI, since it was relatively new to me at that time. Hence, Swiftcord was born! --- @@ -47,7 +47,7 @@ Alpha releases are available at [GitHub Releases](https://github.com/cryptoAlgor ### Homebrew Swiftcord is also available on homebrew as a cask: `brew install swiftcord`. Versions are -lockstepped with alpha releases on GitHub releases. +lock stepped with alpha releases on GitHub releases. @@ -55,7 +55,7 @@ lockstepped with alpha releases on GitHub releases. * OS: macOS Monterey and above (>= 12.0) * Arch: Apple Silicon or Intel (Most releases are universal bundles) -> Note: Note: To open Swiftcord, you may need to right click on the icon > press open. +> Note: Note: To open Swiftcord, you may need to right-click on the icon > press open. > Some older releases were not signed or notarized with an Apple developer account. --- @@ -77,25 +77,25 @@ to expand the answer have not been banned for using Swiftcord with either my main or alt account. I do not take any responsibility for account bans due to the use of Swiftcord, - whether direct or indirect, although there's a very low possibility of that occuring. + whether direct or indirect, although there's a very low possibility of that occurring. I recommend trying Swiftcord with an alt if possible.
Feature x is missing! When will y be implemented? Swiftcord currently is in the alpha stage, and hasn't achieved feature - parity with the official Discord client yet (its quite far behind). + parity with the official Discord client yet (it's quite far behind). Many features are on the roadmap, but I do not currently have a timeline for them. Development is progressing at a fast pace, but sometimes bugs may take an unexpectedly long time to fix. - I appreciate contributions, bug reports and suggestions :) + I appreciate contributions, bug reports, and suggestions :)
Swiftcord just crashed! Although I'm aiming for 0 crashes (which is made easy by Swift), sometimes the unexpected happens xD. If you experience a crash, please - open an issue with appropriete infomation like the line the error - occurs on, relevent logs and what you were doing that might have casued + open an issue with appropriate information like the line the error + occurs on, relevant logs, and what you were doing that might have caused the crash. If you can solve the bug causing the crash, that's even better!
@@ -105,7 +105,7 @@ to expand the answer Implemented most core message-related features from the official client, including basic markdown and embeds, stickers (lottie/PNG), -editing and deleting events. You can now send attachments (both +and editing and deleting events. You can now send attachments (both from the file picker and by dragging and dropping) with your messages too! DMs now have first-class support! @@ -114,7 +114,7 @@ aren't supported yet, refer to the [roadmap](#roadmap) below. Gateway connection event handling is stable, and reconnection is rock solid (as far as I can test). If you encounter a reconnection -bug (not reconnecting, reconnection loop etc), please open an issue +bug (not reconnecting, reconnection loop, etc), please open an issue with the relevant logs. --- @@ -122,17 +122,17 @@ with the relevant logs. ## Roadmap I do not have a definite timeline for when a feature would be implemented, -and they may not neccessarily be implemented in sequence. +and they may not necessarily be implemented in sequence. - ✅ Gateway/REST API Implementation -- ✅ Load server list, channels and message -- ✅ Basic message, channel and server rendering +- ✅ Load server list, channels, and message +- ✅ Basic message, channel, and server rendering - ✅ Rich message rendering (stickers, embeds, markdown, media) - ✅ Message replies - ✅ Load and display full user profile (bio + roles) -- ✅ Save last server and last channel viewed in servers (QoL) +- ✅ Save the last server and last channel viewed in servers (QoL) - ✅ Better loading screen -- ✅ Find and request most optimised photo size from CDN +- ✅ Find and request the most optimized photo size from CDN - ⏱ Partial user and app settings - ✅ DM and group loading - ✅ Display DMs properly in UI @@ -141,12 +141,12 @@ and they may not neccessarily be implemented in sequence. - ❌ User roles + overwrites - ❌ Message notifications - ❌ Full list of users in a server, especially for larger servers (1000+ members) -- ✅ Ordering of channels, servers and categories +- ✅ Ordering of channels, servers, and categories - ❌ Threads support - ❌ Full user settings - ❌ Server creation - ❌ Server discovery -- ❌ Server banner, boost widget and other misc. boosted features +- ❌ Server banner, boost widget, and other misc. boosted features - ❌ Voice channels (ambitious) - ❌ Video channels (very ambitious) @@ -160,14 +160,14 @@ and they may not neccessarily be implemented in sequence. ## Contributions Thank you for popping by! If you know the Discord API well, -have Swift knowledge and feel like contributing, feel free to +have Swift knowledge, and feel like contributing, feel free to make a pull request! Any (positive) contribution is welcome, no matter how small! You can also join the Swiftcord Discord server -to discuss improvements and bugfixes! +to discuss improvements and bug fixes! Found an issue? Ensure it isn't a duplicate, then open a new issue with the appropriate template and fill in the placeholders as -clearly as you can. Responding promptly to follow up comments +clearly as you can. Responding promptly to follow-up comments is appreciated, as debugging is hard without any further input from the OP. @@ -184,11 +184,11 @@ the Free Software Foundation, either version 3 of the License, or This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -The above copyright notice, this permission notice and its license shall be included in all copies or substantial portions of the Software. +The above copyright notice, this permission notice, and its license shall be included in all copies or substantial portions of the Software. -You can find a copy of the GNU General Public License v3 in LICENSE, or https://www.gnu.org/licenses/. +You can find a copy of the GNU General Public License v3 in LICENSE or https://www.gnu.org/licenses/. I ❤️ Open Source From 52f4545fde8e439680af5720c206019556dc1c8e Mon Sep 17 00:00:00 2001 From: vinkwok Date: Tue, 14 Jun 2022 15:43:47 +0800 Subject: [PATCH 09/56] Add some badges, remove redundant phrases in summary --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ac7816b..2139fa7b 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,11 @@ A completely native Discord client for macOS built 100% in Swift and SwiftUI ![Viewing the general-talk channel in the r/MacBookPro server in Swiftcord](README_Resources/heroScreenshot.png) +![Lines of code](https://img.shields.io/tokei/lines/github/SwiftcordApp/Swiftcord?style=for-the-badge) +![Discord](https://img.shields.io/discord/964741354112577557?color=rgb%2888%2C101%2C242%29&label=discord&style=for-the-badge) +![GitHub Repo stars](https://img.shields.io/github/stars/cryptoAlgorithm/Swiftcord?color=%23FECF0F&style=for-the-badge) +![GitHub Sponsors](https://img.shields.io/github/sponsors/cryptoAlgorithm?label=buy%20me%20a%20coffee&logo=buymeacoffee&style=for-the-badge) + This project aims to create a fully functional native Discord client in Swift for macOS from scratch. @@ -14,7 +19,7 @@ the Discord API implementation Swiftcord relies on. **If you like this project, please give it a ⭐ star! It helps motivate me to continue developing it** -### Join the Swiftcord Discord server [here](https://discord.gg/he7n6MGDXS)! +**Consider buying me a coffee ☕️ by sponsoring Swiftcord!** ## Contents * [Motivation](#motivation) @@ -40,12 +45,18 @@ since it was relatively new to me at that time. Hence, Swiftcord was born! ## Releases ### Nightly Builds (Latest fixes/features, might be unstable) +![GitHub Workflow Status](https://img.shields.io/github/workflow/status/SwiftcordApp/Swiftcord/Build%20Canary?style=for-the-badge) + For the latest features and fixes, [a pre-built version of the latest commit is available here](https://nightly.link/SwiftcordApp/Swiftcord/workflows/main/main/Swiftcord_Canary.zip) ### Alpha (More stable, less updated) +![GitHub release (latest by date)](https://img.shields.io/github/v/release/cryptoAlgorithm/Swiftcord?style=for-the-badge) + Alpha releases are available at [GitHub Releases](https://github.com/cryptoAlgorithm/Swiftcord/releases/) ### Homebrew +![homebrew cask](https://img.shields.io/homebrew/cask/v/swiftcord?style=for-the-badge) + Swiftcord is also available on homebrew as a cask: `brew install swiftcord`. Versions are lock stepped with alpha releases on GitHub releases. From 5ec773f2d47b76665ae3358c836c9e286bfae657 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Tue, 14 Jun 2022 20:02:28 +0800 Subject: [PATCH 10/56] Rely on main branch of DiscordKit after merging breaking PR --- Swiftcord.xcodeproj/project.pbxproj | 2 +- Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 50203e24..65b66db9 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -972,7 +972,7 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/SwiftcordApp/DiscordKit"; requirement = { - branch = rearchitect; + branch = main; kind = branch; }; }; diff --git a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved index 104d3cf1..459f1a45 100644 --- a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/SwiftcordApp/DiscordKit", "state" : { - "branch" : "rearchitect", - "revision" : "c0334e29bcf5548dfe54b3d0a7b0df9af27c86eb" + "branch" : "main", + "revision" : "213e0b8817f56cb7cf7fe03443386c330d59009d" } }, { From 44bfb83161b2247adfe13be1f420ad64cf085508 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Tue, 14 Jun 2022 21:57:26 -0400 Subject: [PATCH 11/56] update Xcode version --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a15f8b61..00abbc20 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ jobs: - name: "Select Xcode 13.3.1" uses: devbotsxyz/xcode-select@main with: - version: "13.3.1" + version: "13.4.1" - name: "Import Certificate: Development" uses: devbotsxyz/import-signing-certificate@main From ea349308c34dc9f9c171c3285e214ce9bf3c4316 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Wed, 15 Jun 2022 11:17:13 +0800 Subject: [PATCH 12/56] Do not quit app after all windows closed Fixes #62 --- Swiftcord/AppDelegate.swift | 4 ++-- Swiftcord/SwiftcordApp.swift | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Swiftcord/AppDelegate.swift b/Swiftcord/AppDelegate.swift index b2b01739..73a56877 100644 --- a/Swiftcord/AppDelegate.swift +++ b/Swiftcord/AppDelegate.swift @@ -29,12 +29,12 @@ class AppDelegate: NSObject, NSApplicationDelegate { } } - func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + /*func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { /// Close the app when there are no more open windows /// This is mostly to fix bugs occuring when windows are /// reopened after all windows are closed return true - } + }*/ } private extension AppDelegate { diff --git a/Swiftcord/SwiftcordApp.swift b/Swiftcord/SwiftcordApp.swift index 5ce754b8..cb3eb575 100644 --- a/Swiftcord/SwiftcordApp.swift +++ b/Swiftcord/SwiftcordApp.swift @@ -38,6 +38,7 @@ struct SwiftcordApp: App { ? .dark : (selectedTheme == "light" ? .light : nil)) .onAppear { + guard gateway.socket == nil else { return } guard let token = Keychain.load(key: SwiftcordApp.tokenKeychainKey) else { state.attemptLogin = true return From 06ec59e4e301ed6e8bc2e837211b38f2b873f7de Mon Sep 17 00:00:00 2001 From: vinkwok Date: Wed, 15 Jun 2022 12:05:44 +0800 Subject: [PATCH 13/56] Remove only selected UserDefaults keys when logging out Fix the message input not clearning on send in macOS 13 --- .../Utils/Extensions/MessagesView+.swift | 4 ++++ .../Settings/User/UserSettingsView.swift | 23 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Swiftcord/Utils/Extensions/MessagesView+.swift b/Swiftcord/Utils/Extensions/MessagesView+.swift index ce8a3fef..6d1d84c0 100644 --- a/Swiftcord/Utils/Extensions/MessagesView+.swift +++ b/Swiftcord/Utils/Extensions/MessagesView+.swift @@ -55,6 +55,10 @@ extension MessagesView { internal func sendMessage(with message: String, attachments: [URL]) { lastSentTyping = Date(timeIntervalSince1970: 0) newMessage = "" + if #available(macOS 13, *) { + // Workaround for some race condition, probably a macOS 13 beta bug + DispatchQueue.main.async { newMessage = "" } + } else { newMessage = "" } showingInfoBar = false Task { guard (await restAPI.createChannelMsg( diff --git a/Swiftcord/Views/Settings/User/UserSettingsView.swift b/Swiftcord/Views/Settings/User/UserSettingsView.swift index 05629baa..73723d07 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsView.swift @@ -15,6 +15,27 @@ struct UserSettingsView: View { @State private var selectedLink: SidebarLink? = .account @EnvironmentObject var gateway: DiscordGateway + private let keyPrefixesToRemove = [ + "lastCh.", + "lastSelectedGuild", + "showSendBtn", + "stickerAlwaysAnim", + "theme", + "ttsRate" + ] + + private func logOut() { + for key in UserDefaults.standard.dictionaryRepresentation().keys { + for toRemove in keyPrefixesToRemove { + if key.prefix(toRemove.count) == toRemove { + UserDefaults.standard.removeObject(forKey: key) + break + } + } + } + gateway.logout() + } + var body: some View { NavigationView { List { @@ -45,7 +66,7 @@ struct UserSettingsView: View { Text("settings.user.logOut.confirmation") Text("Note: This will also delete your locally stored preferences") .font(.caption) - Button(role: .destructive) { gateway.logout() } label: { + Button(role: .destructive) { logOut() } label: { Label( "settings.user.logOut", systemImage: "rectangle.portrait.and.arrow.right" From 6f89dfc1d9150d439d495e64cf39874e110e07a0 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Wed, 15 Jun 2022 13:32:49 +0800 Subject: [PATCH 14/56] Send logout POST request to invalidate token when logging out --- Swiftcord.xcodeproj/project.pbxproj | 2 ++ .../xcshareddata/swiftpm/Package.resolved | 18 +++++++++--------- Swiftcord/SwiftcordApp.swift | 1 + Swiftcord/Utils/WebView.swift | 2 +- .../Views/Settings/User/UserSettingsView.swift | 4 ++++ 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 487d5e53..a572ff4d 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -180,6 +180,7 @@ DAAFB5C6282AB56B00807B54 /* AudioCenterManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioCenterManager.swift; sourceTree = ""; }; DAAFB5C8282B689000807B54 /* discord-loading-animation.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "discord-loading-animation.json"; sourceTree = ""; }; DAAFB5CB282B879200807B54 /* Double+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+.swift"; sourceTree = ""; }; + DAB5366028599AC900DD9857 /* DiscordKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DiscordKit; path = ../DiscordKit; sourceTree = ""; }; DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugSettingsView.swift; sourceTree = ""; }; DAE557FA282D00B6001F4EF1 /* typing-animation.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "typing-animation.json"; sourceTree = ""; }; E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array.Channel+.swift"; sourceTree = ""; }; @@ -283,6 +284,7 @@ DA4A887B27C0AF3000720909 = { isa = PBXGroup; children = ( + DAB5366028599AC900DD9857 /* DiscordKit */, 36004E1C283D63E500F0BA73 /* .swiftlint.yml */, DA4A888627C0AF3000720909 /* Swiftcord */, DA4A891727C4B0DF00720909 /* README.md */, diff --git a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved index 459f1a45..4a69a2ee 100644 --- a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -9,15 +9,6 @@ "version" : "4.4.2" } }, - { - "identity" : "discordkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SwiftcordApp/DiscordKit", - "state" : { - "branch" : "main", - "revision" : "213e0b8817f56cb7cf7fe03443386c330d59009d" - } - }, { "identity" : "lottie-ios", "kind" : "remoteSourceControl", @@ -54,6 +45,15 @@ "version" : "2.1.0" } }, + { + "identity" : "swift-docc-plugin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-docc-plugin", + "state" : { + "revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6", + "version" : "1.0.0" + } + }, { "identity" : "swiftui-cached-async-image", "kind" : "remoteSourceControl", diff --git a/Swiftcord/SwiftcordApp.swift b/Swiftcord/SwiftcordApp.swift index cb3eb575..8a28b650 100644 --- a/Swiftcord/SwiftcordApp.swift +++ b/Swiftcord/SwiftcordApp.swift @@ -59,6 +59,7 @@ struct SwiftcordApp: App { Settings { SettingsView() .environmentObject(gateway) + .environmentObject(restAPI) .environmentObject(state) .preferredColorScheme(selectedTheme == "dark" ? .dark diff --git a/Swiftcord/Utils/WebView.swift b/Swiftcord/Utils/WebView.swift index dae1191b..400de7b3 100644 --- a/Swiftcord/Utils/WebView.swift +++ b/Swiftcord/Utils/WebView.swift @@ -96,7 +96,7 @@ struct WebView: NSViewRepresentable { const s = document.createElement('style'); s.innerHTML = ` #app-mount { - background: url(data:image/gif;base64,\(backgroundImageB64 ?? "")); + background: url(data:image/png;base64,\(backgroundImageB64 ?? "")); background-size: cover; background-position: center; } diff --git a/Swiftcord/Views/Settings/User/UserSettingsView.swift b/Swiftcord/Views/Settings/User/UserSettingsView.swift index 73723d07..b99815f1 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsView.swift @@ -8,12 +8,14 @@ import SwiftUI import DiscordKit import DiscordKitCommon +import DiscordKitCore struct UserSettingsView: View { let user: CurrentUser @State private var selectedLink: SidebarLink? = .account @EnvironmentObject var gateway: DiscordGateway + @EnvironmentObject var rest: DiscordREST private let keyPrefixesToRemove = [ "lastCh.", @@ -34,6 +36,8 @@ struct UserSettingsView: View { } } gateway.logout() + Task { await rest.logOut() } + Keychain.remove(key: SwiftcordApp.tokenKeychainKey) } var body: some View { From a504e6124810317bf3739fb62cb4e60db1c6ae69 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Wed, 15 Jun 2022 15:11:57 +0800 Subject: [PATCH 15/56] Revamped login experience * Login now takes up the whole window instead of showing in a sheet * Made style injection and element modification more robust * Styled input fields to be translucent too --- Swiftcord/SwiftcordApp.swift | 39 ++++++++++++++++++------------- Swiftcord/Utils/WebView.swift | 13 +++++++---- Swiftcord/Views/ContentView.swift | 27 --------------------- Swiftcord/Views/LoginView.swift | 37 +++++++++++++++++++++++------ 4 files changed, 62 insertions(+), 54 deletions(-) diff --git a/Swiftcord/SwiftcordApp.swift b/Swiftcord/SwiftcordApp.swift index 8a28b650..1f185b46 100644 --- a/Swiftcord/SwiftcordApp.swift +++ b/Swiftcord/SwiftcordApp.swift @@ -27,25 +27,32 @@ struct SwiftcordApp: App { var body: some Scene { WindowGroup { - ContentView() - .overlay(LoadingView()) - .environmentObject(gateway) - .environmentObject(state) - .environmentObject(restAPI) + if state.attemptLogin { + LoginView() + .environmentObject(gateway) + .environmentObject(state) + .environmentObject(restAPI) + } else { + ContentView() + .overlay(LoadingView()) + .environmentObject(gateway) + .environmentObject(state) + .environmentObject(restAPI) // .environment(\.locale, .init(identifier: "zh-Hans")) // .environment(\.managedObjectContext, persistenceController.container.viewContext) - .preferredColorScheme(selectedTheme == "dark" - ? .dark - : (selectedTheme == "light" ? .light : nil)) - .onAppear { - guard gateway.socket == nil else { return } - guard let token = Keychain.load(key: SwiftcordApp.tokenKeychainKey) else { - state.attemptLogin = true - return + .preferredColorScheme(selectedTheme == "dark" + ? .dark + : (selectedTheme == "light" ? .light : nil)) + .onAppear { + guard gateway.socket == nil else { return } + guard let token = Keychain.load(key: SwiftcordApp.tokenKeychainKey) else { + state.attemptLogin = true + return + } + gateway.connect(token: token) + restAPI.setToken(token: token) } - gateway.connect(token: token) - restAPI.setToken(token: token) - } + } } .commands { CommandGroup(after: .appInfo) { diff --git a/Swiftcord/Utils/WebView.swift b/Swiftcord/Utils/WebView.swift index 400de7b3..728a90c5 100644 --- a/Swiftcord/Utils/WebView.swift +++ b/Swiftcord/Utils/WebView.swift @@ -88,10 +88,8 @@ struct WebView: NSViewRepresentable { // Also overwrite some styles window.onload = () => { - // Remove the oversaturated background - document.querySelector('#app-mount > div[class^="app-"] > div:first-child > svg').remove(); - // Remove the fallback Discord logo - document.querySelector('#app-mount > div[class^="app-"] > div:first-child > a').remove(); + // Remove the oversaturated background and fallback Discord logo + document.querySelectorAll('#app-mount div[class^="characterBackground-"] > *:not(div)').forEach(e => e.remove()); // Some things can only be styled thru a style since they are dynamically modified const s = document.createElement('style'); s.innerHTML = ` @@ -103,6 +101,13 @@ struct WebView: NSViewRepresentable { form[class*="authBox-"] { background-color: rgba(0, 0, 0, .7)!important; -webkit-backdrop-filter: blur(24px) saturate(140%); + border-radius: 12px; + } + .theme-dark { + --input-background: rgba(0, 0, 0, .25)!important; + } + div[class^="select-"] > div > div:nth-child(2) { + background-color: var(--input-background)!important; } `; document.body.appendChild(s); diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index e6b8c28c..f130ef10 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -30,7 +30,6 @@ struct ContentView: View { @State private var selectedGuildID: Snowflake? @State private var loadingGuildID: Snowflake? - @StateObject var loginWVModel: WebViewModel = WebViewModel(link: "https://canary.discord.com/login") @StateObject private var audioManager = AudioCenterManager() @EnvironmentObject var gateway: DiscordGateway @@ -145,32 +144,6 @@ struct ContentView: View { .onChange(of: state.loadingState, perform: { state in if state == .gatewayConn { loadLastSelectedGuild() } }) - // Using .constant to prevent dismissing - .sheet(isPresented: .constant(state.attemptLogin)) { - ZStack(alignment: .topLeading) { - WebView() - .environmentObject(loginWVModel) - .frame(width: 831, height: 580) - Button("Quit", role: .cancel) { exit(0) }.padding(8) - - if !loginWVModel.didFinishLoading { - ZStack { - ProgressView("Loading Discord login...") - .controlSize(.large) - .frame(maxWidth: .infinity, maxHeight: .infinity) - } - .background(.background) - } - } - } - .onChange(of: loginWVModel.token, perform: { token in - if let token = token { - state.attemptLogin = false - Keychain.save(key: SwiftcordApp.tokenKeychainKey, data: token) - gateway.connect(token: token) // Reconnect to the socket with the new token - restAPI.setToken(token: token) - } - }) .onAppear { if state.loadingState == .messageLoad { loadLastSelectedGuild() } diff --git a/Swiftcord/Views/LoginView.swift b/Swiftcord/Views/LoginView.swift index 15154e50..b55cad5e 100644 --- a/Swiftcord/Views/LoginView.swift +++ b/Swiftcord/Views/LoginView.swift @@ -6,15 +6,38 @@ // import SwiftUI +import DiscordKit +import DiscordKitCore + +struct LoginView: View { + @StateObject var loginWVModel: WebViewModel = WebViewModel(link: "https://canary.discord.com/login") + + @EnvironmentObject var gateway: DiscordGateway + @EnvironmentObject var restAPI: DiscordREST + @EnvironmentObject var state: UIState -struct Login: View { var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) - } -} + ZStack { + WebView() + .environmentObject(loginWVModel) -struct Login_Previews: PreviewProvider { - static var previews: some View { - Login() + if !loginWVModel.didFinishLoading { + ZStack { + ProgressView("Loading Discord login...") + .controlSize(.large) + .frame(maxWidth: .infinity, maxHeight: .infinity) + }.background(.background) + } + } + .frame(minWidth: 850, idealWidth: 950, minHeight: 500, idealHeight: 620) + .navigationTitle("Login") + .onChange(of: loginWVModel.token) { token in + if let token = token { + Keychain.save(key: SwiftcordApp.tokenKeychainKey, data: token) + gateway.connect(token: token) // Reconnect to the socket with the new token + restAPI.setToken(token: token) + state.attemptLogin = false + } + } } } From c5152c516bc4273eb918432ea7d162dbb453516d Mon Sep 17 00:00:00 2001 From: vinkwok Date: Wed, 15 Jun 2022 23:08:34 +0800 Subject: [PATCH 16/56] Add onboarding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chinese localisation for this isn’t fully complete yet though --- Swiftcord.xcodeproj/project.pbxproj | 6 +- .../xcshareddata/swiftpm/Package.resolved | 18 ++--- Swiftcord/Views/ContentView.swift | 15 ++++ Swiftcord/Views/OnboardingView.swift | 75 +++++++++++++++++++ .../Settings/User/UserSettingsView.swift | 1 + Swiftcord/en.lproj/Localizable.strings | 19 +++++ Swiftcord/zh-Hans.lproj/Localizable.strings | 19 +++++ 7 files changed, 142 insertions(+), 11 deletions(-) create mode 100644 Swiftcord/Views/OnboardingView.swift diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index a572ff4d..8fd3e169 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -87,6 +87,7 @@ DAAFB5C7282AB56B00807B54 /* AudioCenterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5C6282AB56B00807B54 /* AudioCenterManager.swift */; }; DAAFB5C9282B689000807B54 /* discord-loading-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAAFB5C8282B689000807B54 /* discord-loading-animation.json */; }; DAAFB5CC282B879200807B54 /* Double+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5CB282B879200807B54 /* Double+.swift */; }; + DAB53662285A272D00DD9857 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB53661285A272D00DD9857 /* OnboardingView.swift */; }; DAB6C417284B04DB0066E49D /* DebugSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */; }; DAE557FB282D00B6001F4EF1 /* typing-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAE557FA282D00B6001F4EF1 /* typing-animation.json */; }; E7AF1C27282FA3ED001F78DF /* Array.Channel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */; }; @@ -180,7 +181,7 @@ DAAFB5C6282AB56B00807B54 /* AudioCenterManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioCenterManager.swift; sourceTree = ""; }; DAAFB5C8282B689000807B54 /* discord-loading-animation.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "discord-loading-animation.json"; sourceTree = ""; }; DAAFB5CB282B879200807B54 /* Double+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+.swift"; sourceTree = ""; }; - DAB5366028599AC900DD9857 /* DiscordKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DiscordKit; path = ../DiscordKit; sourceTree = ""; }; + DAB53661285A272D00DD9857 /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = ""; }; DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugSettingsView.swift; sourceTree = ""; }; DAE557FA282D00B6001F4EF1 /* typing-animation.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "typing-animation.json"; sourceTree = ""; }; E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array.Channel+.swift"; sourceTree = ""; }; @@ -284,7 +285,6 @@ DA4A887B27C0AF3000720909 = { isa = PBXGroup; children = ( - DAB5366028599AC900DD9857 /* DiscordKit */, 36004E1C283D63E500F0BA73 /* .swiftlint.yml */, DA4A888627C0AF3000720909 /* Swiftcord */, DA4A891727C4B0DF00720909 /* README.md */, @@ -359,6 +359,7 @@ DA4A88E427C3482A00720909 /* LoginView.swift */, DA2384C527CD1921009E15E0 /* LoadingView.swift */, DAAFB5C4282AB37500807B54 /* MediaControllerView.swift */, + DAB53661285A272D00DD9857 /* OnboardingView.swift */, DA4A888927C0AF3000720909 /* ContentView.swift */, ); path = Views; @@ -643,6 +644,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DAB53662285A272D00DD9857 /* OnboardingView.swift in Sources */, DA520ACB27D4A23A009FD740 /* String+.swift in Sources */, DA57F44428056718001DC46E /* ChannelList.swift in Sources */, DA54D57F28460F3A00B11857 /* ReferenceMessageView.swift in Sources */, diff --git a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4a69a2ee..aa7e79da 100644 --- a/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Swiftcord.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -9,6 +9,15 @@ "version" : "4.4.2" } }, + { + "identity" : "discordkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftcordApp/DiscordKit", + "state" : { + "branch" : "main", + "revision" : "5cc5888a2bd66b7c1575d7c926b12f31d3659fcd" + } + }, { "identity" : "lottie-ios", "kind" : "remoteSourceControl", @@ -45,15 +54,6 @@ "version" : "2.1.0" } }, - { - "identity" : "swift-docc-plugin", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-docc-plugin", - "state" : { - "revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6", - "version" : "1.0.0" - } - }, { "identity" : "swiftui-cached-async-image", "kind" : "remoteSourceControl", diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index f130ef10..f9825386 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -29,6 +29,7 @@ struct ContentView: View { @State private var sheetOpen = false @State private var selectedGuildID: Snowflake? @State private var loadingGuildID: Snowflake? + @State private var presentingOnboarding = false @StateObject private var audioManager = AudioCenterManager() @@ -36,6 +37,8 @@ struct ContentView: View { @EnvironmentObject var restAPI: DiscordREST @EnvironmentObject var state: UIState + @AppStorage("local.seenOnboarding") private var seenOnboarding = false + private let log = Logger(category: "ContentView") private func makeDMGuild() -> Guild { @@ -143,6 +146,7 @@ struct ContentView: View { } .onChange(of: state.loadingState, perform: { state in if state == .gatewayConn { loadLastSelectedGuild() } + if state == .messageLoad, !seenOnboarding { presentingOnboarding = true } }) .onAppear { if state.loadingState == .messageLoad { loadLastSelectedGuild() } @@ -170,6 +174,11 @@ struct ContentView: View { } _ = gateway.socket?.onSessionInvalid.addHandler { state.loadingState = .initial } } + .sheet(isPresented: $presentingOnboarding) { + seenOnboarding = true + } content: { + OnboardingView(presenting: $presentingOnboarding) + } } /*private func addItem() { @@ -208,6 +217,12 @@ struct ContentView: View { }*/ } +extension ContentView { + /*func getReleaseNotes() async -> String { + + }*/ +} + private let itemFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .short diff --git a/Swiftcord/Views/OnboardingView.swift b/Swiftcord/Views/OnboardingView.swift new file mode 100644 index 00000000..100abdd3 --- /dev/null +++ b/Swiftcord/Views/OnboardingView.swift @@ -0,0 +1,75 @@ +// +// OnboardingView.swift +// Swiftcord +// +// Created by Vincent Kwok on 15/6/22. +// + +import SwiftUI + +struct OnboardingView: View { + @Binding var presenting: Bool + + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Group { + Text("onboarding.title").font(.largeTitle) + + Text(appName ?? "") + .foregroundColor(.accentColor) + .font(.system(size: 72)) + .fontWeight(.heavy) + Text("onboarding.subtitle").padding(.top, -20) + } + .padding(.top, 6) + .padding(.horizontal, 8) + + Divider() + + HStack(spacing: 16) { + Image(systemName: "cpu").foregroundColor(.green).font(.system(size: 32)).frame(width: 32) + VStack(alignment: .leading, spacing: 4) { + Text("onboarding.lightweight.header").font(.title3) + Text("onboarding.lightweight.body").opacity(0.75) + } + }.padding(.leading, 4) + HStack(spacing: 16) { + Image(systemName: "checkmark.circle").foregroundColor(.orange).font(.system(size: 32)).frame(width: 32) + VStack(alignment: .leading, spacing: 4) { + Text("onboarding.features.header").font(.title3) + Text("onboarding.features.body").opacity(0.75) + } + }.padding(.leading, 4) + HStack(spacing: 16) { + Image(systemName: "hammer").foregroundColor(.blue).font(.system(size: 32)).frame(width: 32) + VStack(alignment: .leading, spacing: 4) { + Text("onboarding.wip.header").font(.title3) + Text("onboarding.wip.body").opacity(0.75) + } + }.padding(.leading, 4) + + Spacer() + + Text("onboarding.footer").font(.caption) + + Button { + presenting = false + } label: { + Text("action.continue") + .frame(maxWidth: .infinity) + .font(.title3) + .padding(10) + .background(Color.accentColor) + .cornerRadius(4) + } + .buttonStyle(.plain) + } + .padding(16) + .frame(width: 400, height: 530) + } +} + +struct OnboardingView_Previews: PreviewProvider { + static var previews: some View { + OnboardingView(presenting: .constant(true)) + } +} diff --git a/Swiftcord/Views/Settings/User/UserSettingsView.swift b/Swiftcord/Views/Settings/User/UserSettingsView.swift index b99815f1..e4422bb2 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsView.swift @@ -19,6 +19,7 @@ struct UserSettingsView: View { private let keyPrefixesToRemove = [ "lastCh.", + "local.", "lastSelectedGuild", "showSendBtn", "stickerAlwaysAnim", diff --git a/Swiftcord/en.lproj/Localizable.strings b/Swiftcord/en.lproj/Localizable.strings index 06d24c03..dca98943 100644 --- a/Swiftcord/en.lproj/Localizable.strings +++ b/Swiftcord/en.lproj/Localizable.strings @@ -1,3 +1,22 @@ +/* ====== Actions ====== */ +"action.continue" = "Continue"; + +/* ====== Onboarding ====== */ +"onboarding.title" = "Welcome to\n"; + +"onboarding.subtitle" = "A Discord client built and designed exclusively for macOS"; + +"onboarding.lightweight.header" = "Efficient - Light on Resources"; +"onboarding.lightweight.body" = "Uses up to 7x less RAM than Discord with low CPU usage"; + +"onboarding.features.header" = "Well Featured"; +"onboarding.features.body" = "Important core features are implemented, with more in the working"; + +"onboarding.wip.header" = "Work in Progress"; +"onboarding.wip.body" = "Something's not right? Please create an issue or leave a message in the Discord server"; + +"onboarding.footer" = "Swiftcord is alpha software, with limitations and bugs. It currently isn't intended to replace the official client, but hopes to someday."; + /* ====== Loading Cover ====== */ "loader.tip.header" = "Did You Know"; diff --git a/Swiftcord/zh-Hans.lproj/Localizable.strings b/Swiftcord/zh-Hans.lproj/Localizable.strings index 7d1ae41e..3245ed03 100644 --- a/Swiftcord/zh-Hans.lproj/Localizable.strings +++ b/Swiftcord/zh-Hans.lproj/Localizable.strings @@ -1,3 +1,22 @@ +/* ====== Actions ====== */ +"action.continue" = "继续"; + +/* ====== Onboarding ====== */ +"onboarding.title" = "欢迎使用\n"; + +"onboarding.subtitle" = "专为macOS打造和设计的Discord客户端"; + +"onboarding.lightweight.header" = "Efficient - Light on Resources"; +"onboarding.lightweight.body" = "Uses up to 7x less RAM than Discord with low CPU usage"; + +"onboarding.features.header" = "Well Featured"; +"onboarding.features.body" = "Important core features are implemented, with more in the working"; + +"onboarding.wip.header" = "Work in Progress"; +"onboarding.wip.body" = "Something's not right? Please create an issue or leave a message in the Discord server"; + +"onboarding.footer" = "Swiftcord是初期的软件,有限制和错误。它目前并不打算取代官方客户端,但希望有朝一日能够取代。"; + /* ====== Loading Cover ====== */ "loader.tip.header" = "你知道吗"; From 3555fcf5b09bc41ac0b793fe5067bcf400a75d65 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Thu, 16 Jun 2022 10:19:02 -0400 Subject: [PATCH 17/56] weblate test commit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2139fa7b..48d67efb 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ lock stepped with alpha releases on GitHub releases. ### Requirements * OS: macOS Monterey and above (>= 12.0) -* Arch: Apple Silicon or Intel (Most releases are universal bundles) +* Arch: Apple Silicon or Intel (Most releases are universal bundles) > Note: Note: To open Swiftcord, you may need to right-click on the icon > press open. > Some older releases were not signed or notarized with an Apple developer account. From 66f0a911431ed728dc7f2a06d770a5b40723bdf4 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Thu, 16 Jun 2022 12:04:37 -0400 Subject: [PATCH 18/56] Add weblate link to readme.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 48d67efb..a5817604 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ A completely native Discord client for macOS built 100% in Swift and SwiftUI ![Discord](https://img.shields.io/discord/964741354112577557?color=rgb%2888%2C101%2C242%29&label=discord&style=for-the-badge) ![GitHub Repo stars](https://img.shields.io/github/stars/cryptoAlgorithm/Swiftcord?color=%23FECF0F&style=for-the-badge) ![GitHub Sponsors](https://img.shields.io/github/sponsors/cryptoAlgorithm?label=buy%20me%20a%20coffee&logo=buymeacoffee&style=for-the-badge) +![Weblate project translated](https://img.shields.io/weblate/progress/swiftcord?style=for-the-badge) This project aims to create a fully functional native Discord client in Swift for macOS from scratch. @@ -182,6 +183,8 @@ clearly as you can. Responding promptly to follow-up comments is appreciated, as debugging is hard without any further input from the OP. +Want to translate Swiftcord into another language? Head on over to our [Weblate.](https://hosted.weblate.org/projects/swiftcord/swiftcord/) + --- ## Copyright Notice From 8546f6d97717d3c151356da445bedb3e23883c66 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Thu, 16 Jun 2022 12:24:17 -0400 Subject: [PATCH 19/56] Make the badges actually link to somewhere --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a5817604..10cd3edc 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ A completely native Discord client for macOS built 100% in Swift and SwiftUI ![Viewing the general-talk channel in the r/MacBookPro server in Swiftcord](README_Resources/heroScreenshot.png) -![Lines of code](https://img.shields.io/tokei/lines/github/SwiftcordApp/Swiftcord?style=for-the-badge) -![Discord](https://img.shields.io/discord/964741354112577557?color=rgb%2888%2C101%2C242%29&label=discord&style=for-the-badge) -![GitHub Repo stars](https://img.shields.io/github/stars/cryptoAlgorithm/Swiftcord?color=%23FECF0F&style=for-the-badge) -![GitHub Sponsors](https://img.shields.io/github/sponsors/cryptoAlgorithm?label=buy%20me%20a%20coffee&logo=buymeacoffee&style=for-the-badge) -![Weblate project translated](https://img.shields.io/weblate/progress/swiftcord?style=for-the-badge) +[![Lines of code](https://img.shields.io/tokei/lines/github/SwiftcordApp/Swiftcord?style=for-the-badge)]() +[![Discord](https://img.shields.io/discord/964741354112577557?color=rgb%2888%2C101%2C242%29&label=discord&style=for-the-badge)](https://discord.gg/he7n6MGDXS) +[![GitHub Repo stars](https://img.shields.io/github/stars/cryptoAlgorithm/Swiftcord?color=%23FECF0F&style=for-the-badge)](https://github.com/SwiftcordApp/Swiftcord/stargazers) +[![GitHub Sponsors](https://img.shields.io/github/sponsors/cryptoAlgorithm?label=buy%20me%20a%20coffee&logo=buymeacoffee&style=for-the-badge)](https://github.com/sponsors/cryptoAlgorithm) +[![Weblate project translated](https://img.shields.io/weblate/progress/swiftcord?style=for-the-badge)](https://hosted.weblate.org/projects/swiftcord/swiftcord/) This project aims to create a fully functional native Discord client in Swift for macOS from scratch. @@ -46,17 +46,17 @@ since it was relatively new to me at that time. Hence, Swiftcord was born! ## Releases ### Nightly Builds (Latest fixes/features, might be unstable) -![GitHub Workflow Status](https://img.shields.io/github/workflow/status/SwiftcordApp/Swiftcord/Build%20Canary?style=for-the-badge) +[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/SwiftcordApp/Swiftcord/Build%20Canary?style=for-the-badge)](https://nightly.link/SwiftcordApp/Swiftcord/workflows/main/main/Swiftcord_Canary.zip) For the latest features and fixes, [a pre-built version of the latest commit is available here](https://nightly.link/SwiftcordApp/Swiftcord/workflows/main/main/Swiftcord_Canary.zip) ### Alpha (More stable, less updated) -![GitHub release (latest by date)](https://img.shields.io/github/v/release/cryptoAlgorithm/Swiftcord?style=for-the-badge) +[![GitHub release (latest by date)](https://img.shields.io/github/v/release/cryptoAlgorithm/Swiftcord?style=for-the-badge)](https://github.com/cryptoAlgorithm/Swiftcord/releases/) Alpha releases are available at [GitHub Releases](https://github.com/cryptoAlgorithm/Swiftcord/releases/) ### Homebrew -![homebrew cask](https://img.shields.io/homebrew/cask/v/swiftcord?style=for-the-badge) +[![homebrew cask](https://img.shields.io/homebrew/cask/v/swiftcord?style=for-the-badge)](https://formulae.brew.sh/cask/swiftcord) Swiftcord is also available on homebrew as a cask: `brew install swiftcord`. Versions are lock stepped with alpha releases on GitHub releases. From 8ba71acbf0ffb7b63b4d17f981fe508aedfc4ea6 Mon Sep 17 00:00:00 2001 From: 7408647n Date: Thu, 16 Jun 2022 20:25:16 +0200 Subject: [PATCH 20/56] add german translation add german translation --- Swiftcord.xcodeproj/project.pbxproj | 3 + Swiftcord/de.lproj/Localizable.strings | 122 +++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 Swiftcord/de.lproj/Localizable.strings diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 8fd3e169..663bdf46 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -189,6 +189,7 @@ E7AF1C2A282FA400001F78DF /* Guild+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Guild+.swift"; sourceTree = ""; }; E7AF1C32282FB02A001F78DF /* UserSettingsAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsAccountView.swift; sourceTree = ""; }; E7AF1C35282FC2E8001F78DF /* NSTextView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextView+.swift"; sourceTree = ""; }; + F421AC52285BACB200034F59 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -584,6 +585,7 @@ en, "zh-Hans", Base, + de, ); mainGroup = DA4A887B27C0AF3000720909; packageReferences = ( @@ -728,6 +730,7 @@ children = ( DA2ADF302847B13F004A35F2 /* zh-Hans */, DA97BA892848737C00059FD7 /* en */, + F421AC52285BACB200034F59 /* de */, ); name = Localizable.strings; sourceTree = ""; diff --git a/Swiftcord/de.lproj/Localizable.strings b/Swiftcord/de.lproj/Localizable.strings new file mode 100644 index 00000000..ff501489 --- /dev/null +++ b/Swiftcord/de.lproj/Localizable.strings @@ -0,0 +1,122 @@ +/* ====== Actions ====== */ +"action.continue" = "Fortfahren"; + +/* ====== Onboarding ====== */ +"onboarding.title" = "Willkommen zu\n"; + +"onboarding.subtitle" = "Ein Discord-Client erstellt und designt nur für macOS"; + +"onboarding.lightweight.header" = "Effizient - Ressourcen schonend"; +"onboarding.lightweight.body" = "Benutzt bis zu 7x weniger RAM als Discord mit weniger CPU beanspruchung"; + +"onboarding.features.header" = "Gut vorgestellt"; +"onboarding.features.body" = "Wichtige Kern-Funktionen sind umgesetzt, weitere sind in Arbeit"; + +"onboarding.wip.header" = "In Arbeit"; +"onboarding.wip.body" = "Etwas ist nicht richtig? Bitte erstelle einen Fehler oder lass eine Nachricht auf unserem Discord-Server"; + +"onboarding.footer" = "Swiftcord ist eine Alpha-Software, mit Begrenzungen und Fehlern. Zur Zeit ist es kein Ersatzt für den offiziellen Discord-Client, aber irgendwann hoffentlich."; + +/* ====== Loading Cover ====== */ +"loader.tip.header" = "Wusstest du schon"; + +/* ====== User ====== */ +"user.bio" = "Über mich"; + +"user.roles.none" = "Keine Rollen"; + +"user.roles.one" = "Rolle"; + +"user.roles.many" = "Rollen"; + +"user.roles.loading" = "Lade Rollen"; + +"user.note" = "Notiz"; + +/* ====== Message ====== */ +"message.edited.shrunk" = " (bearbeitet)"; + +"message.edited" = " • Bearbeitet: "; + +"message.gone" = "Die Original Nachricht wurde gelöscht."; + +"message.reply.attachment" = "Klicke, um den Anhang zu sehen"; + +/* ====== Server ====== */ +"server.noChannels.header" = "Keine Text Kanäle"; + +"server.noChannels.body" = "Du bist am einem Seltsamen Ort. Du hast entweder keinen Zugriff auf die Text-Kanäle oder es gibt diese auf diesem Server nicht."; + +"server.channel.header %@ %@" = "Dies ist der Anfang von dem #%@ Kanal. %@"; + +"server.channel.title %@" = "Willkommen zu #%@!"; + +"server.channel.noCategory" = "Keine Kategorie"; + +"server.composeMsg.hint %@" = "Nachricht #%@"; + +/* ====== DMs ====== */ +"dm.noChannels.body" = "Wumpus wartet auf seine Freunde. Dies must du aber nicht!"; + +"dm" = "Private Nachricht"; + +"dm.header %@" = "Das ist der Anfang des Privat-Nachriten-Verlaufs **@%@**."; + +"dm.group.header %@" = "Willkommen am Anfang der **%@** Gruppe."; + +"dm.group.composeMsg.hint %@" = "Nachricht %@"; + +"%lld dm.group.memberCount" = "%lld Mitglieder"; + +"dm.composeMsg.hint %@" = "Nachricht @%@"; + +/* ====== Settings ====== */ +"settings.showSendBtn" = "Zeige den Nachricht senden Knopf"; + +"settings.animInteraction" = "Auf dem Desktop Client werden Sticker durch den Fokus oder das berühren der Maus animiert. An mobilen Geräten geschieht dies durch gedrückt-halten."; + +"settings.tts.rate" = "Text-zu-Sprache Geschwindigkeit"; + +"settings.tts.defaultSpeed" = "Standart"; + +"settings.tts.slower" = "Langsamer"; + +"settings.tts.faster" = "Schneller"; + +//////////////////////////// + +"settings.user.logOut" = "Ausloggen"; + +"settings.user.logOut.confirmation" = "Bist du sicher, dass du dich ausloggen möchtest?"; + +"settings.app" = "App"; + +"settings.app.appearance" = "Aussehen"; + +"settings.app.appearance.theme" = "Thema"; + +"settings.app.accessibility" = "Barrierefreiheit"; + +"settings.app.accessibility.stickers" = "Sticker"; + +"settings.app.accessibility.chatInput" = "Chat Eingang"; + +"settings.app.voiceVideo" = "Ton & Video"; + +"settings.app.textImages" = "Text & Bilder"; + +"settings.app.notifs" = "Benachrichtigungen"; + +"settings.app.keybinds" = "Tastenkürzel"; + +"settings.app.lang" = "Sprache"; + +"settings.app.streamer" = "Streamer Modus"; + +"settings.app.advanced" = "Fortgeschritten"; + +"settings.others.debug.actions" = "Aktionen"; + +"settings.others.debug.actions.info" = "Verwende hier keine Optionen, wenn du nicht weißt, was passiert. Einige könnten GeFäHrLiCh sein!"; + +"settings.others.debug.actions.crash" = "Lässt Swiftcord abstürzen (Kein Scherz)"; From af3a8b0e366fa8507462b876d36fc924be34f9e3 Mon Sep 17 00:00:00 2001 From: 7408647n Date: Thu, 16 Jun 2022 20:56:33 +0200 Subject: [PATCH 21/56] fixed spelling mistakes fixed spelling mistakes --- Swiftcord/de.lproj/Localizable.strings | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Swiftcord/de.lproj/Localizable.strings b/Swiftcord/de.lproj/Localizable.strings index ff501489..e66933ae 100644 --- a/Swiftcord/de.lproj/Localizable.strings +++ b/Swiftcord/de.lproj/Localizable.strings @@ -7,7 +7,7 @@ "onboarding.subtitle" = "Ein Discord-Client erstellt und designt nur für macOS"; "onboarding.lightweight.header" = "Effizient - Ressourcen schonend"; -"onboarding.lightweight.body" = "Benutzt bis zu 7x weniger RAM als Discord mit weniger CPU beanspruchung"; +"onboarding.lightweight.body" = "Benutzt bis zu 7x weniger RAM als Discord mit weniger CPU Beanspruchung"; "onboarding.features.header" = "Gut vorgestellt"; "onboarding.features.body" = "Wichtige Kern-Funktionen sind umgesetzt, weitere sind in Arbeit"; @@ -15,7 +15,7 @@ "onboarding.wip.header" = "In Arbeit"; "onboarding.wip.body" = "Etwas ist nicht richtig? Bitte erstelle einen Fehler oder lass eine Nachricht auf unserem Discord-Server"; -"onboarding.footer" = "Swiftcord ist eine Alpha-Software, mit Begrenzungen und Fehlern. Zur Zeit ist es kein Ersatzt für den offiziellen Discord-Client, aber irgendwann hoffentlich."; +"onboarding.footer" = "Swiftcord ist eine Alpha-Software, mit Begrenzungen und Fehlern. Zurzeit ist es kein Ersatzt für den offiziellen Discord-Client, aber irgendwann hoffentlich."; /* ====== Loading Cover ====== */ "loader.tip.header" = "Wusstest du schon"; @@ -38,14 +38,14 @@ "message.edited" = " • Bearbeitet: "; -"message.gone" = "Die Original Nachricht wurde gelöscht."; +"message.gone" = "Die Original-Nachricht wurde gelöscht."; "message.reply.attachment" = "Klicke, um den Anhang zu sehen"; /* ====== Server ====== */ "server.noChannels.header" = "Keine Text Kanäle"; -"server.noChannels.body" = "Du bist am einem Seltsamen Ort. Du hast entweder keinen Zugriff auf die Text-Kanäle oder es gibt diese auf diesem Server nicht."; +"server.noChannels.body" = "Du bist an einem seltsamen Ort. Du hast entweder keinen Zugriff auf die Text-Kanäle oder es gibt diese auf diesem Server nicht."; "server.channel.header %@ %@" = "Dies ist der Anfang von dem #%@ Kanal. %@"; @@ -56,11 +56,11 @@ "server.composeMsg.hint %@" = "Nachricht #%@"; /* ====== DMs ====== */ -"dm.noChannels.body" = "Wumpus wartet auf seine Freunde. Dies must du aber nicht!"; +"dm.noChannels.body" = "Wumpus wartet auf seine Freunde. Dies musst du aber nicht!"; "dm" = "Private Nachricht"; -"dm.header %@" = "Das ist der Anfang des Privat-Nachriten-Verlaufs **@%@**."; +"dm.header %@" = "Das ist der Anfang des Privat-Nachrichten-Verlaufs **@%@**."; "dm.group.header %@" = "Willkommen am Anfang der **%@** Gruppe."; @@ -77,7 +77,7 @@ "settings.tts.rate" = "Text-zu-Sprache Geschwindigkeit"; -"settings.tts.defaultSpeed" = "Standart"; +"settings.tts.defaultSpeed" = "Standard"; "settings.tts.slower" = "Langsamer"; From f40ffb97761127ce63c2037d3a34953c4dd32a81 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Thu, 16 Jun 2022 19:10:29 -0400 Subject: [PATCH 22/56] Import certificates into tmp keychain --- .github/workflows/main.yml | 50 ++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 00abbc20..762f2606 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,18 +25,43 @@ jobs: version: "13.4.1" - name: "Import Certificate: Development" - uses: devbotsxyz/import-signing-certificate@main - with: - certificate-data: ${{ secrets.DEVELOPMENT_CERTIFICATE_DATA }} - certificate-passphrase: ${{ secrets.DEVELOPMENT_CERTIFICATE_PASSPHRASE }} - keychain-password: ${{ secrets.KEYCHAIN_PASSWORD }} + env: + BUILD_CERTIFICATE_BASE64: ${{ secrets.DEVELOPMENT_CERTIFICATE_DATA }} + P12_PASSWORD: ${{ secrets.DEVELOPMENT_CERTIFICATE_PASSPHRASE }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + # create variables + CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 + KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db + + # import certificate and provisioning profile from secrets + echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH + + # create temporary keychain + security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + security set-keychain-settings -lut 21600 $KEYCHAIN_PATH + security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + + # import certificate to keychain + security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH + security list-keychain -d user -s $KEYCHAIN_PATH - name: "Import Certificate: Distribution" - uses: devbotsxyz/import-signing-certificate@main - with: - certificate-data: ${{ secrets.DISTRIBUTION_CERTIFICATE_DATA }} - certificate-passphrase: ${{ secrets.DISTRIBUTION_CERTIFICATE_PASSPHRASE }} - keychain-password: ${{ secrets.KEYCHAIN_PASSWORD }} + env: + BUILD_CERTIFICATE_BASE64: ${{ secrets.DISTRIBUTION_CERTIFICATE_DATA }} + P12_PASSWORD: ${{ secrets.DISTRIBUTION_CERTIFICATE_PASSPHRASE }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + # create variables + CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 + KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db + + # import certificate and provisioning profile from secrets + echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH + + # import certificate to keychain + security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH + security list-keychain -d user -s $KEYCHAIN_PATH - name: "Update Xcode Team ID" run: | @@ -80,5 +105,10 @@ jobs: --token "${{ secrets.APPCENTER_API_TOKEN }}" \ --app "Swiftcord/Swiftcord" \ --xcarchive "Swiftcord.xcarchive" + + - name: Clean up keychain and provisioning profile + if: ${{ always() }} + run: | + security delete-keychain $RUNNER_TEMP/app-signing.keychain-db From d2d6a9e7f533dee6465a97206d3cbb874b5114cd Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Thu, 16 Jun 2022 21:56:39 -0400 Subject: [PATCH 23/56] =?UTF-8?q?Update=20=E2=80=9CAbout=20Swiftcord?= =?UTF-8?q?=E2=80=9D=20window?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - includes the full text of the GNU GENERAL PUBLIC LICENSE Version 3 - change the copyright string to “Made with ❤️ from the Swiftcord Contributors” --- Swiftcord.xcodeproj/project.pbxproj | 12 +- Swiftcord/Resources/Credits.rtf | 682 ++++++++++++++++++++++++++++ 2 files changed, 690 insertions(+), 4 deletions(-) create mode 100644 Swiftcord/Resources/Credits.rtf diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 663bdf46..229f9376 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 36367146283C1B6500A5CBE6 /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36367144283C19E500A5CBE6 /* AVKit.framework */; }; 3684BB59283C696E005045AE /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 3684BB58283C696E005045AE /* Sparkle */; }; 3684BB5B283C69C5005045AE /* Sparkle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3684BB5A283C69C5005045AE /* Sparkle.swift */; }; + 36BC29F3285C162500A8B316 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 36BC29F2285C162500A8B316 /* Credits.rtf */; }; 900F6DA1284A1C0C000B6D29 /* GeneratedBuildSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 900F6DA0284A1C0C000B6D29 /* GeneratedBuildSettings.swift */; }; DA03DA3F284F1E9200257790 /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA03DA3E284F1E9200257790 /* Keychain.swift */; }; DA2384A127CB9714009E15E0 /* Font+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2384A027CB9714009E15E0 /* Font+.swift */; }; @@ -101,6 +102,7 @@ 36004E1C283D63E500F0BA73 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; 36367144283C19E500A5CBE6 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; }; 3684BB5A283C69C5005045AE /* Sparkle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sparkle.swift; sourceTree = ""; }; + 36BC29F2285C162500A8B316 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; }; 900F6D9D284A1A92000B6D29 /* Project Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Project Shared.xcconfig"; sourceTree = ""; }; 900F6D9E284A1ADE000B6D29 /* Project Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Project Debug.xcconfig"; sourceTree = ""; }; 900F6D9F284A1AE6000B6D29 /* Project Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Project Release.xcconfig"; sourceTree = ""; }; @@ -369,6 +371,7 @@ DA520ABD27D322F0009FD740 /* Resources */ = { isa = PBXGroup; children = ( + 36BC29F2285C162500A8B316 /* Credits.rtf */, E7AF1C24282F9F44001F78DF /* Animations */, DA23843C27CB9621009E15E0 /* Fonts */, ); @@ -612,6 +615,7 @@ DAAFB5C9282B689000807B54 /* discord-loading-animation.json in Resources */, DA2384BB27CBC2CE009E15E0 /* GintoMedium.otf in Resources */, DA4A888F27C0AF3200720909 /* Preview Assets.xcassets in Resources */, + 36BC29F3285C162500A8B316 /* Credits.rtf in Resources */, DA2ADF312847B13F004A35F2 /* Localizable.strings in Resources */, DA4A888C27C0AF3200720909 /* Assets.xcassets in Resources */, DA2384BA27CBC2CE009E15E0 /* GintoBold.otf in Resources */, @@ -870,13 +874,13 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; - DEVELOPMENT_TEAM = Q382QLKDG3; + DEVELOPMENT_TEAM = RJNC97Y8QD; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Swiftcord/Info.plist; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; - INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 Vincent Kwok.\nAll rights reserved."; + INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", @@ -901,13 +905,13 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; - DEVELOPMENT_TEAM = Q382QLKDG3; + DEVELOPMENT_TEAM = RJNC97Y8QD; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Swiftcord/Info.plist; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; - INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 Vincent Kwok.\nAll rights reserved."; + INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", diff --git a/Swiftcord/Resources/Credits.rtf b/Swiftcord/Resources/Credits.rtf new file mode 100644 index 00000000..002b4404 --- /dev/null +++ b/Swiftcord/Resources/Credits.rtf @@ -0,0 +1,682 @@ +{\rtf1\ansi\ansicpg1252\cocoartf2638 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 SFProText-Regular;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\margl1440\margr1440\vieww9000\viewh8400\viewkind0 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 + +\f0\fs24 \cf0 GNU GENERAL PUBLIC LICENSE\ + Version 3, 29 June 2007\ +\ + Copyright (C) 2007 Free Software Foundation, Inc. \ + Everyone is permitted to copy and distribute verbatim copies\ + of this license document, but changing it is not allowed.\ +\ + Preamble\ +\ + The GNU General Public License is a free, copyleft license for\ +software and other kinds of works.\ +\ + The licenses for most software and other practical works are designed\ +to take away your freedom to share and change the works. By contrast,\ +the GNU General Public License is intended to guarantee your freedom to\ +share and change all versions of a program--to make sure it remains free\ +software for all its users. We, the Free Software Foundation, use the\ +GNU General Public License for most of our software; it applies also to\ +any other work released this way by its authors. You can apply it to\ +your programs, too.\ +\ + When we speak of free software, we are referring to freedom, not\ +price. Our General Public Licenses are designed to make sure that you\ +have the freedom to distribute copies of free software (and charge for\ +them if you wish), that you receive source code or can get it if you\ +want it, that you can change the software or use pieces of it in new\ +free programs, and that you know you can do these things.\ +\ + To protect your rights, we need to prevent others from denying you\ +these rights or asking you to surrender the rights. Therefore, you have\ +certain responsibilities if you distribute copies of the software, or if\ +you modify it: responsibilities to respect the freedom of others.\ +\ + For example, if you distribute copies of such a program, whether\ +gratis or for a fee, you must pass on to the recipients the same\ +freedoms that you received. You must make sure that they, too, receive\ +or can get the source code. And you must show them these terms so they\ +know their rights.\ +\ + Developers that use the GNU GPL protect your rights with two steps:\ +(1) assert copyright on the software, and (2) offer you this License\ +giving you legal permission to copy, distribute and/or modify it.\ +\ + For the developers' and authors' protection, the GPL clearly explains\ +that there is no warranty for this free software. For both users' and\ +authors' sake, the GPL requires that modified versions be marked as\ +changed, so that their problems will not be attributed erroneously to\ +authors of previous versions.\ +\ + Some devices are designed to deny users access to install or run\ +modified versions of the software inside them, although the manufacturer\ +can do so. This is fundamentally incompatible with the aim of\ +protecting users' freedom to change the software. The systematic\ +pattern of such abuse occurs in the area of products for individuals to\ +use, which is precisely where it is most unacceptable. Therefore, we\ +have designed this version of the GPL to prohibit the practice for those\ +products. If such problems arise substantially in other domains, we\ +stand ready to extend this provision to those domains in future versions\ +of the GPL, as needed to protect the freedom of users.\ +\ + Finally, every program is threatened constantly by software patents.\ +States should not allow patents to restrict development and use of\ +software on general-purpose computers, but in those that do, we wish to\ +avoid the special danger that patents applied to a free program could\ +make it effectively proprietary. To prevent this, the GPL assures that\ +patents cannot be used to render the program non-free.\ +\ + The precise terms and conditions for copying, distribution and\ +modification follow.\ +\ + TERMS AND CONDITIONS\ +\ + 0. Definitions.\ +\ + "This License" refers to version 3 of the GNU General Public License.\ +\ + "Copyright" also means copyright-like laws that apply to other kinds of\ +works, such as semiconductor masks.\ +\ + "The Program" refers to any copyrightable work licensed under this\ +License. Each licensee is addressed as "you". "Licensees" and\ +"recipients" may be individuals or organizations.\ +\ + To "modify" a work means to copy from or adapt all or part of the work\ +in a fashion requiring copyright permission, other than the making of an\ +exact copy. The resulting work is called a "modified version" of the\ +earlier work or a work "based on" the earlier work.\ +\ + A "covered work" means either the unmodified Program or a work based\ +on the Program.\ +\ + To "propagate" a work means to do anything with it that, without\ +permission, would make you directly or secondarily liable for\ +infringement under applicable copyright law, except executing it on a\ +computer or modifying a private copy. Propagation includes copying,\ +distribution (with or without modification), making available to the\ +public, and in some countries other activities as well.\ +\ + To "convey" a work means any kind of propagation that enables other\ +parties to make or receive copies. Mere interaction with a user through\ +a computer network, with no transfer of a copy, is not conveying.\ +\ + An interactive user interface displays "Appropriate Legal Notices"\ +to the extent that it includes a convenient and prominently visible\ +feature that (1) displays an appropriate copyright notice, and (2)\ +tells the user that there is no warranty for the work (except to the\ +extent that warranties are provided), that licensees may convey the\ +work under this License, and how to view a copy of this License. If\ +the interface presents a list of user commands or options, such as a\ +menu, a prominent item in the list meets this criterion.\ +\ + 1. Source Code.\ +\ + The "source code" for a work means the preferred form of the work\ +for making modifications to it. "Object code" means any non-source\ +form of a work.\ +\ + A "Standard Interface" means an interface that either is an official\ +standard defined by a recognized standards body, or, in the case of\ +interfaces specified for a particular programming language, one that\ +is widely used among developers working in that language.\ +\ + The "System Libraries" of an executable work include anything, other\ +than the work as a whole, that (a) is included in the normal form of\ +packaging a Major Component, but which is not part of that Major\ +Component, and (b) serves only to enable use of the work with that\ +Major Component, or to implement a Standard Interface for which an\ +implementation is available to the public in source code form. A\ +"Major Component", in this context, means a major essential component\ +(kernel, window system, and so on) of the specific operating system\ +(if any) on which the executable work runs, or a compiler used to\ +produce the work, or an object code interpreter used to run it.\ +\ + The "Corresponding Source" for a work in object code form means all\ +the source code needed to generate, install, and (for an executable\ +work) run the object code and to modify the work, including scripts to\ +control those activities. However, it does not include the work's\ +System Libraries, or general-purpose tools or generally available free\ +programs which are used unmodified in performing those activities but\ +which are not part of the work. For example, Corresponding Source\ +includes interface definition files associated with source files for\ +the work, and the source code for shared libraries and dynamically\ +linked subprograms that the work is specifically designed to require,\ +such as by intimate data communication or control flow between those\ +subprograms and other parts of the work.\ +\ + The Corresponding Source need not include anything that users\ +can regenerate automatically from other parts of the Corresponding\ +Source.\ +\ + The Corresponding Source for a work in source code form is that\ +same work.\ +\ + 2. Basic Permissions.\ +\ + All rights granted under this License are granted for the term of\ +copyright on the Program, and are irrevocable provided the stated\ +conditions are met. This License explicitly affirms your unlimited\ +permission to run the unmodified Program. The output from running a\ +covered work is covered by this License only if the output, given its\ +content, constitutes a covered work. This License acknowledges your\ +rights of fair use or other equivalent, as provided by copyright law.\ +\ + You may make, run and propagate covered works that you do not\ +convey, without conditions so long as your license otherwise remains\ +in force. You may convey covered works to others for the sole purpose\ +of having them make modifications exclusively for you, or provide you\ +with facilities for running those works, provided that you comply with\ +the terms of this License in conveying all material for which you do\ +not control copyright. Those thus making or running the covered works\ +for you must do so exclusively on your behalf, under your direction\ +and control, on terms that prohibit them from making any copies of\ +your copyrighted material outside their relationship with you.\ +\ + Conveying under any other circumstances is permitted solely under\ +the conditions stated below. Sublicensing is not allowed; section 10\ +makes it unnecessary.\ +\ + 3. Protecting Users' Legal Rights From Anti-Circumvention Law.\ +\ + No covered work shall be deemed part of an effective technological\ +measure under any applicable law fulfilling obligations under article\ +11 of the WIPO copyright treaty adopted on 20 December 1996, or\ +similar laws prohibiting or restricting circumvention of such\ +measures.\ +\ + When you convey a covered work, you waive any legal power to forbid\ +circumvention of technological measures to the extent such circumvention\ +is effected by exercising rights under this License with respect to\ +the covered work, and you disclaim any intention to limit operation or\ +modification of the work as a means of enforcing, against the work's\ +users, your or third parties' legal rights to forbid circumvention of\ +technological measures.\ +\ + 4. Conveying Verbatim Copies.\ +\ + You may convey verbatim copies of the Program's source code as you\ +receive it, in any medium, provided that you conspicuously and\ +appropriately publish on each copy an appropriate copyright notice;\ +keep intact all notices stating that this License and any\ +non-permissive terms added in accord with section 7 apply to the code;\ +keep intact all notices of the absence of any warranty; and give all\ +recipients a copy of this License along with the Program.\ +\ + You may charge any price or no price for each copy that you convey,\ +and you may offer support or warranty protection for a fee.\ +\ + 5. Conveying Modified Source Versions.\ +\ + You may convey a work based on the Program, or the modifications to\ +produce it from the Program, in the form of source code under the\ +terms of section 4, provided that you also meet all of these conditions:\ +\ + a) The work must carry prominent notices stating that you modified\ + it, and giving a relevant date.\ +\ + b) The work must carry prominent notices stating that it is\ + released under this License and any conditions added under section\ + 7. This requirement modifies the requirement in section 4 to\ + "keep intact all notices".\ +\ + c) You must license the entire work, as a whole, under this\ + License to anyone who comes into possession of a copy. This\ + License will therefore apply, along with any applicable section 7\ + additional terms, to the whole of the work, and all its parts,\ + regardless of how they are packaged. This License gives no\ + permission to license the work in any other way, but it does not\ + invalidate such permission if you have separately received it.\ +\ + d) If the work has interactive user interfaces, each must display\ + Appropriate Legal Notices; however, if the Program has interactive\ + interfaces that do not display Appropriate Legal Notices, your\ + work need not make them do so.\ +\ + A compilation of a covered work with other separate and independent\ +works, which are not by their nature extensions of the covered work,\ +and which are not combined with it such as to form a larger program,\ +in or on a volume of a storage or distribution medium, is called an\ +"aggregate" if the compilation and its resulting copyright are not\ +used to limit the access or legal rights of the compilation's users\ +beyond what the individual works permit. Inclusion of a covered work\ +in an aggregate does not cause this License to apply to the other\ +parts of the aggregate.\ +\ + 6. Conveying Non-Source Forms.\ +\ + You may convey a covered work in object code form under the terms\ +of sections 4 and 5, provided that you also convey the\ +machine-readable Corresponding Source under the terms of this License,\ +in one of these ways:\ +\ + a) Convey the object code in, or embodied in, a physical product\ + (including a physical distribution medium), accompanied by the\ + Corresponding Source fixed on a durable physical medium\ + customarily used for software interchange.\ +\ + b) Convey the object code in, or embodied in, a physical product\ + (including a physical distribution medium), accompanied by a\ + written offer, valid for at least three years and valid for as\ + long as you offer spare parts or customer support for that product\ + model, to give anyone who possesses the object code either (1) a\ + copy of the Corresponding Source for all the software in the\ + product that is covered by this License, on a durable physical\ + medium customarily used for software interchange, for a price no\ + more than your reasonable cost of physically performing this\ + conveying of source, or (2) access to copy the\ + Corresponding Source from a network server at no charge.\ +\ + c) Convey individual copies of the object code with a copy of the\ + written offer to provide the Corresponding Source. This\ + alternative is allowed only occasionally and noncommercially, and\ + only if you received the object code with such an offer, in accord\ + with subsection 6b.\ +\ + d) Convey the object code by offering access from a designated\ + place (gratis or for a charge), and offer equivalent access to the\ + Corresponding Source in the same way through the same place at no\ + further charge. You need not require recipients to copy the\ + Corresponding Source along with the object code. If the place to\ + copy the object code is a network server, the Corresponding Source\ + may be on a different server (operated by you or a third party)\ + that supports equivalent copying facilities, provided you maintain\ + clear directions next to the object code saying where to find the\ + Corresponding Source. Regardless of what server hosts the\ + Corresponding Source, you remain obligated to ensure that it is\ + available for as long as needed to satisfy these requirements.\ +\ + e) Convey the object code using peer-to-peer transmission, provided\ + you inform other peers where the object code and Corresponding\ + Source of the work are being offered to the general public at no\ + charge under subsection 6d.\ +\ + A separable portion of the object code, whose source code is excluded\ +from the Corresponding Source as a System Library, need not be\ +included in conveying the object code work.\ +\ + A "User Product" is either (1) a "consumer product", which means any\ +tangible personal property which is normally used for personal, family,\ +or household purposes, or (2) anything designed or sold for incorporation\ +into a dwelling. In determining whether a product is a consumer product,\ +doubtful cases shall be resolved in favor of coverage. For a particular\ +product received by a particular user, "normally used" refers to a\ +typical or common use of that class of product, regardless of the status\ +of the particular user or of the way in which the particular user\ +actually uses, or expects or is expected to use, the product. A product\ +is a consumer product regardless of whether the product has substantial\ +commercial, industrial or non-consumer uses, unless such uses represent\ +the only significant mode of use of the product.\ +\ + "Installation Information" for a User Product means any methods,\ +procedures, authorization keys, or other information required to install\ +and execute modified versions of a covered work in that User Product from\ +a modified version of its Corresponding Source. The information must\ +suffice to ensure that the continued functioning of the modified object\ +code is in no case prevented or interfered with solely because\ +modification has been made.\ +\ + If you convey an object code work under this section in, or with, or\ +specifically for use in, a User Product, and the conveying occurs as\ +part of a transaction in which the right of possession and use of the\ +User Product is transferred to the recipient in perpetuity or for a\ +fixed term (regardless of how the transaction is characterized), the\ +Corresponding Source conveyed under this section must be accompanied\ +by the Installation Information. But this requirement does not apply\ +if neither you nor any third party retains the ability to install\ +modified object code on the User Product (for example, the work has\ +been installed in ROM).\ +\ + The requirement to provide Installation Information does not include a\ +requirement to continue to provide support service, warranty, or updates\ +for a work that has been modified or installed by the recipient, or for\ +the User Product in which it has been modified or installed. Access to a\ +network may be denied when the modification itself materially and\ +adversely affects the operation of the network or violates the rules and\ +protocols for communication across the network.\ +\ + Corresponding Source conveyed, and Installation Information provided,\ +in accord with this section must be in a format that is publicly\ +documented (and with an implementation available to the public in\ +source code form), and must require no special password or key for\ +unpacking, reading or copying.\ +\ + 7. Additional Terms.\ +\ + "Additional permissions" are terms that supplement the terms of this\ +License by making exceptions from one or more of its conditions.\ +Additional permissions that are applicable to the entire Program shall\ +be treated as though they were included in this License, to the extent\ +that they are valid under applicable law. If additional permissions\ +apply only to part of the Program, that part may be used separately\ +under those permissions, but the entire Program remains governed by\ +this License without regard to the additional permissions.\ +\ + When you convey a copy of a covered work, you may at your option\ +remove any additional permissions from that copy, or from any part of\ +it. (Additional permissions may be written to require their own\ +removal in certain cases when you modify the work.) You may place\ +additional permissions on material, added by you to a covered work,\ +for which you have or can give appropriate copyright permission.\ +\ + Notwithstanding any other provision of this License, for material you\ +add to a covered work, you may (if authorized by the copyright holders of\ +that material) supplement the terms of this License with terms:\ +\ + a) Disclaiming warranty or limiting liability differently from the\ + terms of sections 15 and 16 of this License; or\ +\ + b) Requiring preservation of specified reasonable legal notices or\ + author attributions in that material or in the Appropriate Legal\ + Notices displayed by works containing it; or\ +\ + c) Prohibiting misrepresentation of the origin of that material, or\ + requiring that modified versions of such material be marked in\ + reasonable ways as different from the original version; or\ +\ + d) Limiting the use for publicity purposes of names of licensors or\ + authors of the material; or\ +\ + e) Declining to grant rights under trademark law for use of some\ + trade names, trademarks, or service marks; or\ +\ + f) Requiring indemnification of licensors and authors of that\ + material by anyone who conveys the material (or modified versions of\ + it) with contractual assumptions of liability to the recipient, for\ + any liability that these contractual assumptions directly impose on\ + those licensors and authors.\ +\ + All other non-permissive additional terms are considered "further\ +restrictions" within the meaning of section 10. If the Program as you\ +received it, or any part of it, contains a notice stating that it is\ +governed by this License along with a term that is a further\ +restriction, you may remove that term. If a license document contains\ +a further restriction but permits relicensing or conveying under this\ +License, you may add to a covered work material governed by the terms\ +of that license document, provided that the further restriction does\ +not survive such relicensing or conveying.\ +\ + If you add terms to a covered work in accord with this section, you\ +must place, in the relevant source files, a statement of the\ +additional terms that apply to those files, or a notice indicating\ +where to find the applicable terms.\ +\ + Additional terms, permissive or non-permissive, may be stated in the\ +form of a separately written license, or stated as exceptions;\ +the above requirements apply either way.\ +\ + 8. Termination.\ +\ + You may not propagate or modify a covered work except as expressly\ +provided under this License. Any attempt otherwise to propagate or\ +modify it is void, and will automatically terminate your rights under\ +this License (including any patent licenses granted under the third\ +paragraph of section 11).\ +\ + However, if you cease all violation of this License, then your\ +license from a particular copyright holder is reinstated (a)\ +provisionally, unless and until the copyright holder explicitly and\ +finally terminates your license, and (b) permanently, if the copyright\ +holder fails to notify you of the violation by some reasonable means\ +prior to 60 days after the cessation.\ +\ + Moreover, your license from a particular copyright holder is\ +reinstated permanently if the copyright holder notifies you of the\ +violation by some reasonable means, this is the first time you have\ +received notice of violation of this License (for any work) from that\ +copyright holder, and you cure the violation prior to 30 days after\ +your receipt of the notice.\ +\ + Termination of your rights under this section does not terminate the\ +licenses of parties who have received copies or rights from you under\ +this License. If your rights have been terminated and not permanently\ +reinstated, you do not qualify to receive new licenses for the same\ +material under section 10.\ +\ + 9. Acceptance Not Required for Having Copies.\ +\ + You are not required to accept this License in order to receive or\ +run a copy of the Program. Ancillary propagation of a covered work\ +occurring solely as a consequence of using peer-to-peer transmission\ +to receive a copy likewise does not require acceptance. However,\ +nothing other than this License grants you permission to propagate or\ +modify any covered work. These actions infringe copyright if you do\ +not accept this License. Therefore, by modifying or propagating a\ +covered work, you indicate your acceptance of this License to do so.\ +\ + 10. Automatic Licensing of Downstream Recipients.\ +\ + Each time you convey a covered work, the recipient automatically\ +receives a license from the original licensors, to run, modify and\ +propagate that work, subject to this License. You are not responsible\ +for enforcing compliance by third parties with this License.\ +\ + An "entity transaction" is a transaction transferring control of an\ +organization, or substantially all assets of one, or subdividing an\ +organization, or merging organizations. If propagation of a covered\ +work results from an entity transaction, each party to that\ +transaction who receives a copy of the work also receives whatever\ +licenses to the work the party's predecessor in interest had or could\ +give under the previous paragraph, plus a right to possession of the\ +Corresponding Source of the work from the predecessor in interest, if\ +the predecessor has it or can get it with reasonable efforts.\ +\ + You may not impose any further restrictions on the exercise of the\ +rights granted or affirmed under this License. For example, you may\ +not impose a license fee, royalty, or other charge for exercise of\ +rights granted under this License, and you may not initiate litigation\ +(including a cross-claim or counterclaim in a lawsuit) alleging that\ +any patent claim is infringed by making, using, selling, offering for\ +sale, or importing the Program or any portion of it.\ +\ + 11. Patents.\ +\ + A "contributor" is a copyright holder who authorizes use under this\ +License of the Program or a work on which the Program is based. The\ +work thus licensed is called the contributor's "contributor version".\ +\ + A contributor's "essential patent claims" are all patent claims\ +owned or controlled by the contributor, whether already acquired or\ +hereafter acquired, that would be infringed by some manner, permitted\ +by this License, of making, using, or selling its contributor version,\ +but do not include claims that would be infringed only as a\ +consequence of further modification of the contributor version. For\ +purposes of this definition, "control" includes the right to grant\ +patent sublicenses in a manner consistent with the requirements of\ +this License.\ +\ + Each contributor grants you a non-exclusive, worldwide, royalty-free\ +patent license under the contributor's essential patent claims, to\ +make, use, sell, offer for sale, import and otherwise run, modify and\ +propagate the contents of its contributor version.\ +\ + In the following three paragraphs, a "patent license" is any express\ +agreement or commitment, however denominated, not to enforce a patent\ +(such as an express permission to practice a patent or covenant not to\ +sue for patent infringement). To "grant" such a patent license to a\ +party means to make such an agreement or commitment not to enforce a\ +patent against the party.\ +\ + If you convey a covered work, knowingly relying on a patent license,\ +and the Corresponding Source of the work is not available for anyone\ +to copy, free of charge and under the terms of this License, through a\ +publicly available network server or other readily accessible means,\ +then you must either (1) cause the Corresponding Source to be so\ +available, or (2) arrange to deprive yourself of the benefit of the\ +patent license for this particular work, or (3) arrange, in a manner\ +consistent with the requirements of this License, to extend the patent\ +license to downstream recipients. "Knowingly relying" means you have\ +actual knowledge that, but for the patent license, your conveying the\ +covered work in a country, or your recipient's use of the covered work\ +in a country, would infringe one or more identifiable patents in that\ +country that you have reason to believe are valid.\ +\ + If, pursuant to or in connection with a single transaction or\ +arrangement, you convey, or propagate by procuring conveyance of, a\ +covered work, and grant a patent license to some of the parties\ +receiving the covered work authorizing them to use, propagate, modify\ +or convey a specific copy of the covered work, then the patent license\ +you grant is automatically extended to all recipients of the covered\ +work and works based on it.\ +\ + A patent license is "discriminatory" if it does not include within\ +the scope of its coverage, prohibits the exercise of, or is\ +conditioned on the non-exercise of one or more of the rights that are\ +specifically granted under this License. You may not convey a covered\ +work if you are a party to an arrangement with a third party that is\ +in the business of distributing software, under which you make payment\ +to the third party based on the extent of your activity of conveying\ +the work, and under which the third party grants, to any of the\ +parties who would receive the covered work from you, a discriminatory\ +patent license (a) in connection with copies of the covered work\ +conveyed by you (or copies made from those copies), or (b) primarily\ +for and in connection with specific products or compilations that\ +contain the covered work, unless you entered into that arrangement,\ +or that patent license was granted, prior to 28 March 2007.\ +\ + Nothing in this License shall be construed as excluding or limiting\ +any implied license or other defenses to infringement that may\ +otherwise be available to you under applicable patent law.\ +\ + 12. No Surrender of Others' Freedom.\ +\ + If conditions are imposed on you (whether by court order, agreement or\ +otherwise) that contradict the conditions of this License, they do not\ +excuse you from the conditions of this License. If you cannot convey a\ +covered work so as to satisfy simultaneously your obligations under this\ +License and any other pertinent obligations, then as a consequence you may\ +not convey it at all. For example, if you agree to terms that obligate you\ +to collect a royalty for further conveying from those to whom you convey\ +the Program, the only way you could satisfy both those terms and this\ +License would be to refrain entirely from conveying the Program.\ +\ + 13. Use with the GNU Affero General Public License.\ +\ + Notwithstanding any other provision of this License, you have\ +permission to link or combine any covered work with a work licensed\ +under version 3 of the GNU Affero General Public License into a single\ +combined work, and to convey the resulting work. The terms of this\ +License will continue to apply to the part which is the covered work,\ +but the special requirements of the GNU Affero General Public License,\ +section 13, concerning interaction through a network will apply to the\ +combination as such.\ +\ + 14. Revised Versions of this License.\ +\ + The Free Software Foundation may publish revised and/or new versions of\ +the GNU General Public License from time to time. Such new versions will\ +be similar in spirit to the present version, but may differ in detail to\ +address new problems or concerns.\ +\ + Each version is given a distinguishing version number. If the\ +Program specifies that a certain numbered version of the GNU General\ +Public License "or any later version" applies to it, you have the\ +option of following the terms and conditions either of that numbered\ +version or of any later version published by the Free Software\ +Foundation. If the Program does not specify a version number of the\ +GNU General Public License, you may choose any version ever published\ +by the Free Software Foundation.\ +\ + If the Program specifies that a proxy can decide which future\ +versions of the GNU General Public License can be used, that proxy's\ +public statement of acceptance of a version permanently authorizes you\ +to choose that version for the Program.\ +\ + Later license versions may give you additional or different\ +permissions. However, no additional obligations are imposed on any\ +author or copyright holder as a result of your choosing to follow a\ +later version.\ +\ + 15. Disclaimer of Warranty.\ +\ + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\ +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\ +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY\ +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\ +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\ +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\ +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\ +ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\ +\ + 16. Limitation of Liability.\ +\ + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\ +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\ +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\ +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\ +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\ +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\ +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\ +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\ +SUCH DAMAGES.\ +\ + 17. Interpretation of Sections 15 and 16.\ +\ + If the disclaimer of warranty and limitation of liability provided\ +above cannot be given local legal effect according to their terms,\ +reviewing courts shall apply local law that most closely approximates\ +an absolute waiver of all civil liability in connection with the\ +Program, unless a warranty or assumption of liability accompanies a\ +copy of the Program in return for a fee.\ +\ + END OF TERMS AND CONDITIONS\ +\ + How to Apply These Terms to Your New Programs\ +\ + If you develop a new program, and you want it to be of the greatest\ +possible use to the public, the best way to achieve this is to make it\ +free software which everyone can redistribute and change under these terms.\ +\ + To do so, attach the following notices to the program. It is safest\ +to attach them to the start of each source file to most effectively\ +state the exclusion of warranty; and each file should have at least\ +the "copyright" line and a pointer to where the full notice is found.\ +\ + Swiftcord\ + Copyright (C) 2022 Vincent Kwok\ +\ + This program is free software: you can redistribute it and/or modify\ + it under the terms of the GNU General Public License as published by\ + the Free Software Foundation, either version 3 of the License, or\ + (at your option) any later version.\ +\ + This program is distributed in the hope that it will be useful,\ + but WITHOUT ANY WARRANTY; without even the implied warranty of\ + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\ + GNU General Public License for more details.\ +\ + You should have received a copy of the GNU General Public License\ + along with this program. If not, see .\ +\ +Also add information on how to contact you by electronic and paper mail.\ +\ + If the program does terminal interaction, make it output a short\ +notice like this when it starts in an interactive mode:\ +\ + Copyright (C) 2022 Vincent Kwok\ + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\ + This is free software, and you are welcome to redistribute it\ + under certain conditions; type `show c' for details.\ +\ +The hypothetical commands `show w' and `show c' should show the appropriate\ +parts of the General Public License. Of course, your program's commands\ +might be different; for a GUI interface, you would use an "about box".\ +\ + You should also get your employer (if you work as a programmer) or school,\ +if any, to sign a "copyright disclaimer" for the program, if necessary.\ +For more information on this, and how to apply and follow the GNU GPL, see\ +.\ +\ + The GNU General Public License does not permit incorporating your program\ +into proprietary programs. If your program is a subroutine library, you\ +may consider it more useful to permit linking proprietary applications with\ +the library. If this is what you want to do, use the GNU Lesser General\ +Public License instead of this License. But first, please read\ +.\ +} \ No newline at end of file From 00a15e1327edd72f541508d622de32291ea93680 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Fri, 17 Jun 2022 13:38:23 +0800 Subject: [PATCH 24/56] Add onboarding and fetch release notes from GitHub API --- Swiftcord.xcodeproj/project.pbxproj | 36 +++++++ .../ButtonStyles/DiscordChannelButton.swift | 26 ++++++ Swiftcord/ButtonStyles/FlatButtonStyle.swift | 26 ++++++ .../Utils/Extensions/AnyTransition+.swift | 18 ++++ Swiftcord/Utils/Extensions/Text+.swift | 8 +- Swiftcord/Utils/GitHub/GitHubAPI.swift | 37 ++++++++ Swiftcord/Utils/GitHub/GitHubStructs.swift | 66 +++++++++++++ Swiftcord/Views/ContentView.swift | 33 +++++-- Swiftcord/Views/OnboardingView.swift | 93 ++++++++++++++++--- Swiftcord/Views/Server/ChannelButton.swift | 18 ---- 10 files changed, 318 insertions(+), 43 deletions(-) create mode 100644 Swiftcord/ButtonStyles/DiscordChannelButton.swift create mode 100644 Swiftcord/ButtonStyles/FlatButtonStyle.swift create mode 100644 Swiftcord/Utils/Extensions/AnyTransition+.swift create mode 100644 Swiftcord/Utils/GitHub/GitHubAPI.swift create mode 100644 Swiftcord/Utils/GitHub/GitHubStructs.swift diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 229f9376..e1f7dc18 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -89,6 +89,11 @@ DAAFB5C9282B689000807B54 /* discord-loading-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAAFB5C8282B689000807B54 /* discord-loading-animation.json */; }; DAAFB5CC282B879200807B54 /* Double+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5CB282B879200807B54 /* Double+.swift */; }; DAB53662285A272D00DD9857 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB53661285A272D00DD9857 /* OnboardingView.swift */; }; + DAB53665285ACED100DD9857 /* GitHubAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB53664285ACED100DD9857 /* GitHubAPI.swift */; }; + DAB53668285AD11000DD9857 /* DiscordChannelButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB53667285AD11000DD9857 /* DiscordChannelButton.swift */; }; + DAB5366B285AD15900DD9857 /* FlatButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB5366A285AD15900DD9857 /* FlatButtonStyle.swift */; }; + DAB5366E285AEDF800DD9857 /* GitHubStructs.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB5366D285AEDF800DD9857 /* GitHubStructs.swift */; }; + DAB53670285B693700DD9857 /* AnyTransition+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB5366F285B693700DD9857 /* AnyTransition+.swift */; }; DAB6C417284B04DB0066E49D /* DebugSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */; }; DAE557FB282D00B6001F4EF1 /* typing-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAE557FA282D00B6001F4EF1 /* typing-animation.json */; }; E7AF1C27282FA3ED001F78DF /* Array.Channel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */; }; @@ -184,6 +189,11 @@ DAAFB5C8282B689000807B54 /* discord-loading-animation.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "discord-loading-animation.json"; sourceTree = ""; }; DAAFB5CB282B879200807B54 /* Double+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+.swift"; sourceTree = ""; }; DAB53661285A272D00DD9857 /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = ""; }; + DAB53664285ACED100DD9857 /* GitHubAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHubAPI.swift; sourceTree = ""; }; + DAB53667285AD11000DD9857 /* DiscordChannelButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscordChannelButton.swift; sourceTree = ""; }; + DAB5366A285AD15900DD9857 /* FlatButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlatButtonStyle.swift; sourceTree = ""; }; + DAB5366D285AEDF800DD9857 /* GitHubStructs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHubStructs.swift; sourceTree = ""; }; + DAB5366F285B693700DD9857 /* AnyTransition+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnyTransition+.swift"; sourceTree = ""; }; DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugSettingsView.swift; sourceTree = ""; }; DAE557FA282D00B6001F4EF1 /* typing-animation.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "typing-animation.json"; sourceTree = ""; }; E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array.Channel+.swift"; sourceTree = ""; }; @@ -311,6 +321,7 @@ 900F6D9C284A1A75000B6D29 /* Configurations */, DA520ABD27D322F0009FD740 /* Resources */, DA4A88E327C3481700720909 /* Views */, + DAB53666285AD0F100DD9857 /* ButtonStyles */, DA7720CE283F182700D3C335 /* Commands */, DA4A88DC27C3272500720909 /* Utils */, DA32EF6327CB770E00A9ED72 /* DataModels */, @@ -338,6 +349,7 @@ DA4A88DC27C3272500720909 /* Utils */ = { isa = PBXGroup; children = ( + DAB53663285ACEBB00DD9857 /* GitHub */, DA520AE327D76BF8009FD740 /* Extensions */, DA520AC127D37863009FD740 /* MergeStructs */, DA03DA3E284F1E9200257790 /* Keychain.swift */, @@ -415,6 +427,7 @@ DA585C9827E1F6AC00FA4EE0 /* View+.swift */, DA54D57B2845C36E00B11857 /* MessagesView+.swift */, DA2BD30D284CCC9800EBB8D6 /* Text+.swift */, + DAB5366F285B693700DD9857 /* AnyTransition+.swift */, ); path = Extensions; sourceTree = ""; @@ -459,6 +472,24 @@ path = Utils; sourceTree = ""; }; + DAB53663285ACEBB00DD9857 /* GitHub */ = { + isa = PBXGroup; + children = ( + DAB53664285ACED100DD9857 /* GitHubAPI.swift */, + DAB5366D285AEDF800DD9857 /* GitHubStructs.swift */, + ); + path = GitHub; + sourceTree = ""; + }; + DAB53666285AD0F100DD9857 /* ButtonStyles */ = { + isa = PBXGroup; + children = ( + DAB53667285AD11000DD9857 /* DiscordChannelButton.swift */, + DAB5366A285AD15900DD9857 /* FlatButtonStyle.swift */, + ); + path = ButtonStyles; + sourceTree = ""; + }; E7938D3D28329BFF00B8DC94 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -657,12 +688,15 @@ DA32EF2427C6249000A9ED72 /* MessagesView.swift in Sources */, DA97BA8C2849C0FA00059FD7 /* Cache.swift in Sources */, DA03DA3F284F1E9200257790 /* Keychain.swift in Sources */, + DAB53670285B693700DD9857 /* AnyTransition+.swift in Sources */, E7AF1C27282FA3ED001F78DF /* Array.Channel+.swift in Sources */, DA520AC327D37873009FD740 /* MergePartialMessage.swift in Sources */, + DAB53665285ACED100DD9857 /* GitHubAPI.swift in Sources */, E7AF1C36282FC2E8001F78DF /* NSTextView+.swift in Sources */, 900F6DA1284A1C0C000B6D29 /* GeneratedBuildSettings.swift in Sources */, DA32EF3027C676B300A9ED72 /* WrapperLottieView.swift in Sources */, DA32EF3927C77E3300A9ED72 /* AttachmentView.swift in Sources */, + DAB5366E285AEDF800DD9857 /* GitHubStructs.swift in Sources */, DA2384A127CB9714009E15E0 /* Font+.swift in Sources */, DAAFB5C1282A64CD00807B54 /* LoFiMessageView.swift in Sources */, DA520AC727D39A00009FD740 /* CurrentUserFooter.swift in Sources */, @@ -670,6 +704,7 @@ DA4A889127C0AF3200720909 /* Persistence.swift in Sources */, DA2384C627CD1921009E15E0 /* LoadingView.swift in Sources */, DA54D5762844B9C500B11857 /* CurrentUser+.swift in Sources */, + DAB53668285AD11000DD9857 /* DiscordChannelButton.swift in Sources */, DA520AD727D4D17A009FD740 /* MiscSettingsView.swift in Sources */, DA32EF3F27C7C1D000A9ED72 /* MessageInputView.swift in Sources */, DA520AD327D4D073009FD740 /* AppSettingsView.swift in Sources */, @@ -687,6 +722,7 @@ DA4A891427C49B1100720909 /* ServerButton.swift in Sources */, DA520AD927D4E7A4009FD740 /* LargeUserProfileView.swift in Sources */, DA54D57A2844E41A00B11857 /* ProfileBadges.swift in Sources */, + DAB5366B285AD15900DD9857 /* FlatButtonStyle.swift in Sources */, DA520ACF27D4CE5E009FD740 /* UserSettingsView.swift in Sources */, DA67491B2833D5A9001F51CC /* AboutSwiftcordView.swift in Sources */, E7AF1C2B282FA400001F78DF /* Guild+.swift in Sources */, diff --git a/Swiftcord/ButtonStyles/DiscordChannelButton.swift b/Swiftcord/ButtonStyles/DiscordChannelButton.swift new file mode 100644 index 00000000..82526aa0 --- /dev/null +++ b/Swiftcord/ButtonStyles/DiscordChannelButton.swift @@ -0,0 +1,26 @@ +// +// DiscordChannelButton.swift +// Swiftcord +// +// Created by Vincent Kwok on 16/6/22. +// + +import SwiftUI + +struct DiscordChannelButton: ButtonStyle { + let isSelected: Bool + @State var isHovered: Bool = false + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .buttonStyle(.borderless) + .font(.system(size: 14, weight: isSelected ? .medium : .regular)) + .foregroundColor(isSelected ? Color(nsColor: .labelColor) : .gray) + .accentColor(isSelected ? Color(nsColor: .labelColor) : .gray) + .background( + RoundedRectangle(cornerRadius: 4) + .fill(isSelected ? .gray.opacity(0.3) : (isHovered ? .gray.opacity(0.2) : .clear)) + ) + .onHover(perform: { isHovered = $0 }) + } +} diff --git a/Swiftcord/ButtonStyles/FlatButtonStyle.swift b/Swiftcord/ButtonStyles/FlatButtonStyle.swift new file mode 100644 index 00000000..a653fadb --- /dev/null +++ b/Swiftcord/ButtonStyles/FlatButtonStyle.swift @@ -0,0 +1,26 @@ +// +// FlatButtonStyle.swift +// Swiftcord +// +// Created by Vincent Kwok on 16/6/22. +// + +import SwiftUI + +struct FlatButtonStyle: ButtonStyle { + @Environment(\.controlSize) private var controlSize: ControlSize + @Environment(\.isEnabled) private var enabled: Bool + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .frame(height: controlSize == .large ? 48 : 32) + .font(controlSize == .large ? .title3 : .body) + .background( + enabled + ? Color.accentColor.opacity(configuration.isPressed ? 0.7 : 1) + : .gray.opacity(0.25) + ) + .cornerRadius(4) + .animation(.easeOut(duration: 0.17), value: configuration.isPressed) + } +} diff --git a/Swiftcord/Utils/Extensions/AnyTransition+.swift b/Swiftcord/Utils/Extensions/AnyTransition+.swift new file mode 100644 index 00000000..24eca3f4 --- /dev/null +++ b/Swiftcord/Utils/Extensions/AnyTransition+.swift @@ -0,0 +1,18 @@ +// +// AnyTransition+.swift +// Swiftcord +// +// Created by Vincent Kwok on 16/6/22. +// + +import SwiftUI + +extension AnyTransition { + // From https://stackoverflow.com/a/69696690/ + static var backslide: AnyTransition { + AnyTransition.asymmetric( + insertion: .move(edge: .trailing), + removal: .move(edge: .leading) + ) + } +} diff --git a/Swiftcord/Utils/Extensions/Text+.swift b/Swiftcord/Utils/Extensions/Text+.swift index 3ba9e7b0..d35dcf38 100644 --- a/Swiftcord/Utils/Extensions/Text+.swift +++ b/Swiftcord/Utils/Extensions/Text+.swift @@ -9,12 +9,16 @@ import Foundation import SwiftUI extension Text { - init(markdown: String, fallback: AttributedString = "") { + init( + markdown: String, + fallback: AttributedString = "", + syntax: AttributedString.MarkdownParsingOptions.InterpretedSyntax = .inlineOnlyPreservingWhitespace + ) { self.init( (try? AttributedString( markdown: markdown, options: AttributedString.MarkdownParsingOptions( - interpretedSyntax: .inlineOnlyPreservingWhitespace + interpretedSyntax: syntax ) )) ?? fallback ) diff --git a/Swiftcord/Utils/GitHub/GitHubAPI.swift b/Swiftcord/Utils/GitHub/GitHubAPI.swift new file mode 100644 index 00000000..ef46fcf9 --- /dev/null +++ b/Swiftcord/Utils/GitHub/GitHubAPI.swift @@ -0,0 +1,37 @@ +// +// ghAPIs.swift +// Swiftcord +// +// Created by Vincent Kwok on 16/6/22. +// + +import Foundation + +/// A rudimentary GitHub API "implementation" that only implements the specific +/// endpoints required for various functionality in Swiftcord +/// +/// I'm well aware better implementations of GitHub's API exist, for example +/// [OctoKit](https://github.com/nerdishbynature/octokit.swift), +/// but I do not want to rely on yet another package for something only sparingly used. +struct GitHubAPI { + private static let baseURL = URL(string: "https://api.github.com")! + + static func getReleaseByTag( + org: String, + repo: String, + tag: String + ) async throws -> GHRelease { + let url = GitHubAPI.baseURL + .appendingPathComponent("repos") + .appendingPathComponent(org) + .appendingPathComponent(repo) + .appendingPathComponent("releases") + .appendingPathComponent("tags") + .appendingPathComponent(tag) + let (data, _) = try await URLSession.shared.data(from: url) + + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .iso8601 + return try decoder.decode(GHRelease.self, from: data) + } +} diff --git a/Swiftcord/Utils/GitHub/GitHubStructs.swift b/Swiftcord/Utils/GitHub/GitHubStructs.swift new file mode 100644 index 00000000..78339961 --- /dev/null +++ b/Swiftcord/Utils/GitHub/GitHubStructs.swift @@ -0,0 +1,66 @@ +// +// GitHubStructs.swift +// Swiftcord +// +// Created by Vincent Kwok on 16/6/22. +// + +import Foundation + +enum GHUserType: String, Codable { + case user = "User" +} + +struct GHAuthor: Codable { + let login: String + let id: Int + let avatar_url: URL + let url: URL + let html_url: URL + let followers_url: URL + let following_url: String // URL is not a valid URL + let gists_url: String + let starred_url: String + let subscriptions_url: URL + let organizations_url: URL + let repos_url: URL + let events_url: String + let received_events_url: URL + let type: GHUserType + let site_admin: Bool +} + +struct GHReleaseAsset: Codable { + let url: URL + let id: Int + let name: String + let uploader: GHAuthor + let content_type: String + let state: String + let size: Int + let download_count: Int + let created_at: Date + let updated_at: Date + let browser_download_url: URL +} + +struct GHRelease: Codable { + let url: URL + let assets_url: URL + let upload_url: String + let html_url: URL + let id: Int + let author: GHAuthor + let tag_name: String + let target_commitish: String + let name: String + let draft: Bool + let prerelease: Bool + let created_at: Date + let published_at: Date + let assets: [GHReleaseAsset] + let tarball_url: URL + let zipball_url: URL + let body: String + let mentions_count: Int +} diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index f9825386..77128915 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -30,6 +30,8 @@ struct ContentView: View { @State private var selectedGuildID: Snowflake? @State private var loadingGuildID: Snowflake? @State private var presentingOnboarding = false + @State private var skipWhatsNew = false + @State private var whatsNewMarkdown: String? @StateObject private var audioManager = AudioCenterManager() @@ -38,6 +40,7 @@ struct ContentView: View { @EnvironmentObject var state: UIState @AppStorage("local.seenOnboarding") private var seenOnboarding = false + @AppStorage("local.previousBuild") private var prevBuild: String? private let log = Logger(category: "ContentView") @@ -146,7 +149,21 @@ struct ContentView: View { } .onChange(of: state.loadingState, perform: { state in if state == .gatewayConn { loadLastSelectedGuild() } - if state == .messageLoad, !seenOnboarding { presentingOnboarding = true } + if state == .messageLoad, + !seenOnboarding || prevBuild != Bundle.main.infoDictionary?["CFBundleVersion"] as? String { + if !seenOnboarding { presentingOnboarding = true } + Task { + do { + whatsNewMarkdown = try await GitHubAPI + .getReleaseByTag(org: "SwiftcordApp", repo: "Swiftcord", tag: "v0.4.1") + .body + } catch { + skipWhatsNew = true + } + presentingOnboarding = true + print(whatsNewMarkdown) + } + } }) .onAppear { if state.loadingState == .messageLoad { loadLastSelectedGuild() } @@ -176,8 +193,14 @@ struct ContentView: View { } .sheet(isPresented: $presentingOnboarding) { seenOnboarding = true + prevBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String } content: { - OnboardingView(presenting: $presentingOnboarding) + OnboardingView( + skipOnboarding: seenOnboarding, + skipWhatsNew: skipWhatsNew, + newMarkdown: $whatsNewMarkdown, + presenting: $presentingOnboarding + ) } } @@ -217,12 +240,6 @@ struct ContentView: View { }*/ } -extension ContentView { - /*func getReleaseNotes() async -> String { - - }*/ -} - private let itemFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .short diff --git a/Swiftcord/Views/OnboardingView.swift b/Swiftcord/Views/OnboardingView.swift index 100abdd3..1663ceb7 100644 --- a/Swiftcord/Views/OnboardingView.swift +++ b/Swiftcord/Views/OnboardingView.swift @@ -7,10 +7,13 @@ import SwiftUI -struct OnboardingView: View { +struct OnboardingWelcomeView: View { @Binding var presenting: Bool + @Binding var showingNew: Bool + let loadingNew: Bool + let hasNew: Bool - var body: some View { + var body: some View { VStack(alignment: .leading, spacing: 16) { Group { Text("onboarding.title").font(.largeTitle) @@ -22,6 +25,7 @@ struct OnboardingView: View { } .padding(.top, 6) .padding(.horizontal, 8) + .fixedSize(horizontal: false, vertical: true) Divider() @@ -29,21 +33,27 @@ struct OnboardingView: View { Image(systemName: "cpu").foregroundColor(.green).font(.system(size: 32)).frame(width: 32) VStack(alignment: .leading, spacing: 4) { Text("onboarding.lightweight.header").font(.title3) - Text("onboarding.lightweight.body").opacity(0.75) + Text("onboarding.lightweight.body") + .opacity(0.75) + .fixedSize(horizontal: false, vertical: true) } }.padding(.leading, 4) HStack(spacing: 16) { Image(systemName: "checkmark.circle").foregroundColor(.orange).font(.system(size: 32)).frame(width: 32) VStack(alignment: .leading, spacing: 4) { Text("onboarding.features.header").font(.title3) - Text("onboarding.features.body").opacity(0.75) + Text("onboarding.features.body") + .opacity(0.75) + .fixedSize(horizontal: false, vertical: true) } }.padding(.leading, 4) HStack(spacing: 16) { Image(systemName: "hammer").foregroundColor(.blue).font(.system(size: 32)).frame(width: 32) VStack(alignment: .leading, spacing: 4) { Text("onboarding.wip.header").font(.title3) - Text("onboarding.wip.body").opacity(0.75) + Text("onboarding.wip.body") + .opacity(0.75) + .fixedSize(horizontal: false, vertical: true) } }.padding(.leading, 4) @@ -52,24 +62,77 @@ struct OnboardingView: View { Text("onboarding.footer").font(.caption) Button { - presenting = false + if hasNew { + withAnimation { + showingNew = true + } + } else { + presenting = false + } } label: { - Text("action.continue") - .frame(maxWidth: .infinity) - .font(.title3) - .padding(10) - .background(Color.accentColor) - .cornerRadius(4) + if loadingNew { + ProgressView() + .controlSize(.small) + .frame(maxWidth: .infinity) + } else { + Text(hasNew ? "action.continue" : "Done") + .frame(maxWidth: .infinity) + } } - .buttonStyle(.plain) + .buttonStyle(FlatButtonStyle()) + .controlSize(.large) + .disabled(loadingNew) } .padding(16) - .frame(width: 400, height: 530) + .frame(width: 450, height: 550) + } +} + +struct OnboardingView: View { + let skipOnboarding: Bool + let skipWhatsNew: Bool + @Binding var newMarkdown: String? + + @State private var showingNew = false + @Binding var presenting: Bool + + var body: some View { + if let newMarkdown = newMarkdown, showingNew || skipOnboarding { + VStack(alignment: .leading, spacing: 0) { + Text("What's New").font(.title) + Divider().padding(.top, 16) + ScrollView { + Spacer(minLength: 16) + Text(markdown: newMarkdown, syntax: .inlineOnly) + Spacer(minLength: 16) + } + Divider().padding(.bottom, 16) + Button { + presenting = false + } label: { + Text("Done").frame(maxWidth: .infinity) + } + .controlSize(.large) + .buttonStyle(FlatButtonStyle()) + } + .padding(16) + .frame(width: 450, height: 550) + .transition(.backslide) + } else { + OnboardingWelcomeView( + presenting: $presenting, + showingNew: $showingNew, + loadingNew: newMarkdown == nil && !skipWhatsNew, + hasNew: newMarkdown != nil + ) + .transition(.backslide) + } } } struct OnboardingView_Previews: PreviewProvider { static var previews: some View { - OnboardingView(presenting: .constant(true)) + // OnboardingView(presenting: .constant(true)) + EmptyView() } } diff --git a/Swiftcord/Views/Server/ChannelButton.swift b/Swiftcord/Views/Server/ChannelButton.swift index a14faba7..d436b68d 100644 --- a/Swiftcord/Views/Server/ChannelButton.swift +++ b/Swiftcord/Views/Server/ChannelButton.swift @@ -86,21 +86,3 @@ struct DMButton: View { } } } - -struct DiscordChannelButton: ButtonStyle { - let isSelected: Bool - @State var isHovered: Bool = false - - func makeBody(configuration: Configuration) -> some View { - configuration.label - .buttonStyle(.borderless) - .font(.system(size: 14, weight: isSelected ? .medium : .regular)) - .foregroundColor(isSelected ? Color(nsColor: .labelColor) : .gray) - .accentColor(isSelected ? Color(nsColor: .labelColor) : .gray) - .background( - RoundedRectangle(cornerRadius: 4) - .fill(isSelected ? .gray.opacity(0.3) : (isHovered ? .gray.opacity(0.2) : .clear)) - ) - .onHover(perform: { isHovered = $0 }) - } -} From 7691065e1916fc169e1b6e0443e934c245a691bb Mon Sep 17 00:00:00 2001 From: Jonas Agnezi <32183575+agnezi@users.noreply.github.com> Date: Sun, 19 Jun 2022 11:39:13 -0300 Subject: [PATCH 25/56] Update README.md Fix text, remove the duplicated word "that" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10cd3edc..816b6ede 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ me to continue developing it** Swiftcord was created to offer a Discord-like UI and experience while having the performance and memory benefits of native apps. The idea started brewing when I was tight on RAM, then noticed Discord using 600+MB of RAM. -I then realized that that was the perfect opportunity to explore SwiftUI, +I then realized that was the perfect opportunity to explore SwiftUI, since it was relatively new to me at that time. Hence, Swiftcord was born! --- From 688789f476f8159322f935b0c3cb26a9ceffea55 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Thu, 23 Jun 2022 10:48:22 -0400 Subject: [PATCH 26/56] Update main.yml --- .github/workflows/main.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 762f2606..1b8692e5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -69,7 +69,9 @@ jobs: sed -i '' "s/$TEAMID/ RJNC97Y8QD;/g" Swiftcord.xcodeproj/project.pbxproj - name: "Archive" - run: xcodebuild -workspace Swiftcord.xcworkspace -scheme Swiftcord -configuration Release archive -archivePath Swiftcord.xcarchive COMPILER_INDEX_STORE_ENABLE=NO APPCENTER_APP_SECRET="${{ secrets.APPCENTER_APP_SECRET }}" | xcpretty + run: | + xcodebuild -workspace Swiftcord.xcworkspace -scheme Swiftcord -configuration Release archive -archivePath Swiftcord.xcarchive \ + COMPILER_INDEX_STORE_ENABLE=NO APPCENTER_APP_SECRET="${{ secrets.APPCENTER_APP_SECRET }}" "OTHER_CODE_SIGN_FLAGS=--keychain $RUNNER_TEMP/app-signing.keychain-db" | xcpretty - name: "Export & Sign Release Build" uses: devbotsxyz/xcode-export-archive@main From d2994f69592b4365ceba08901e85033d8b49b23d Mon Sep 17 00:00:00 2001 From: DeepSource Bot Date: Sat, 25 Jun 2022 04:33:38 +0000 Subject: [PATCH 27/56] Add .deepsource.toml --- .deepsource.toml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml new file mode 100644 index 00000000..1f05ea0f --- /dev/null +++ b/.deepsource.toml @@ -0,0 +1,5 @@ +version = 1 + +[[analyzers]] +name = "shell" +enabled = true \ No newline at end of file From e33d0f1a60af1f610a794cc3b602238a7eee24c2 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Sat, 25 Jun 2022 23:16:08 -0400 Subject: [PATCH 28/56] Prepare for Xcode Cloud --- Swiftcord.xcodeproj/project.pbxproj | 506 +++++++++++++++++- .../xcschemes/Swiftcord (App Store).xcscheme | 78 +++ Swiftcord/Swiftcord (App Store).plist | 8 + Swiftcord/SwiftcordApp.swift | 4 + 4 files changed, 594 insertions(+), 2 deletions(-) create mode 100644 Swiftcord.xcodeproj/xcshareddata/xcschemes/Swiftcord (App Store).xcscheme create mode 100644 Swiftcord/Swiftcord (App Store).plist diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index e1f7dc18..fa36d8d2 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -8,6 +8,98 @@ /* Begin PBXBuildFile section */ 36367146283C1B6500A5CBE6 /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36367144283C19E500A5CBE6 /* AVKit.framework */; }; + 3642993E286801C900483D0A /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB53661285A272D00DD9857 /* OnboardingView.swift */; }; + 3642993F286801C900483D0A /* String+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520ACA27D4A23A009FD740 /* String+.swift */; }; + 36429940286801C900483D0A /* ChannelList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA57F44328056718001DC46E /* ChannelList.swift */; }; + 36429941286801C900483D0A /* ReferenceMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA54D57E28460F3A00B11857 /* ReferenceMessageView.swift */; }; + 36429942286801C900483D0A /* MessagesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF2327C6249000A9ED72 /* MessagesView.swift */; }; + 36429943286801C900483D0A /* Cache.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA97BA8B2849C0FA00059FD7 /* Cache.swift */; }; + 36429944286801C900483D0A /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA03DA3E284F1E9200257790 /* Keychain.swift */; }; + 36429945286801C900483D0A /* AnyTransition+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB5366F285B693700DD9857 /* AnyTransition+.swift */; }; + 36429946286801C900483D0A /* Array.Channel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C26282FA3ED001F78DF /* Array.Channel+.swift */; }; + 36429947286801C900483D0A /* MergePartialMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520AC227D37873009FD740 /* MergePartialMessage.swift */; }; + 36429948286801C900483D0A /* GitHubAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB53664285ACED100DD9857 /* GitHubAPI.swift */; }; + 36429949286801C900483D0A /* NSTextView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C35282FC2E8001F78DF /* NSTextView+.swift */; }; + 3642994A286801C900483D0A /* GeneratedBuildSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 900F6DA0284A1C0C000B6D29 /* GeneratedBuildSettings.swift */; }; + 3642994B286801C900483D0A /* WrapperLottieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF2F27C676B300A9ED72 /* WrapperLottieView.swift */; }; + 3642994C286801C900483D0A /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF3827C77E3300A9ED72 /* AttachmentView.swift */; }; + 3642994D286801C900483D0A /* GitHubStructs.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB5366D285AEDF800DD9857 /* GitHubStructs.swift */; }; + 3642994E286801C900483D0A /* Font+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2384A027CB9714009E15E0 /* Font+.swift */; }; + 3642994F286801C900483D0A /* LoFiMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5C0282A64CD00807B54 /* LoFiMessageView.swift */; }; + 36429950286801C900483D0A /* CurrentUserFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520AC627D39A00009FD740 /* CurrentUserFooter.swift */; }; + 36429951286801C900483D0A /* TagCloudView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF4B27C8BF5000A9ED72 /* TagCloudView.swift */; }; + 36429952286801C900483D0A /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4A889027C0AF3200720909 /* Persistence.swift */; }; + 36429953286801C900483D0A /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2384C527CD1921009E15E0 /* LoadingView.swift */; }; + 36429954286801C900483D0A /* CurrentUser+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA54D5752844B9C500B11857 /* CurrentUser+.swift */; }; + 36429955286801C900483D0A /* DiscordChannelButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB53667285AD11000DD9857 /* DiscordChannelButton.swift */; }; + 36429956286801C900483D0A /* MiscSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520AD627D4D17A009FD740 /* MiscSettingsView.swift */; }; + 36429957286801C900483D0A /* MessageInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF3E27C7C1D000A9ED72 /* MessageInputView.swift */; }; + 36429958286801C900483D0A /* AppSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520AD227D4D073009FD740 /* AppSettingsView.swift */; }; + 36429959286801C900483D0A /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4A889B27C0B23C00720909 /* WebView.swift */; }; + 3642995A286801C900483D0A /* DebugSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB6C416284B04DB0066E49D /* DebugSettingsView.swift */; }; + 3642995B286801C900483D0A /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4A88E427C3482A00720909 /* LoginView.swift */; }; + 3642995C286801C900483D0A /* UIStateEnv.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF5827CB5F4F00A9ED72 /* UIStateEnv.swift */; }; + 3642995D286801C900483D0A /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF2527C62E6900A9ED72 /* MessageView.swift */; }; + 3642995E286801C900483D0A /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4A888927C0AF3000720909 /* ContentView.swift */; }; + 3642995F286801C900483D0A /* ChannelButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA57F44528065209001DC46E /* ChannelButton.swift */; }; + 36429960286801C900483D0A /* CacheModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF6427CB772300A9ED72 /* CacheModel.xcdatamodeld */; }; + 36429961286801C900483D0A /* UserSettingsAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C32282FB02A001F78DF /* UserSettingsAccountView.swift */; }; + 36429962286801C900483D0A /* Bool+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520AE127D76BEB009FD740 /* Bool+.swift */; }; + 36429963286801C900483D0A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2802782808337B00B14E5C /* AppDelegate.swift */; }; + 36429964286801C900483D0A /* ServerButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4A891327C49B1000720909 /* ServerButton.swift */; }; + 36429965286801C900483D0A /* LargeUserProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520AD827D4E7A3009FD740 /* LargeUserProfileView.swift */; }; + 36429966286801C900483D0A /* ProfileBadges.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA54D5792844E41A00B11857 /* ProfileBadges.swift */; }; + 36429967286801C900483D0A /* FlatButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB5366A285AD15900DD9857 /* FlatButtonStyle.swift */; }; + 36429968286801C900483D0A /* UserSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520ACE27D4CE5E009FD740 /* UserSettingsView.swift */; }; + 36429969286801C900483D0A /* AboutSwiftcordView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA67491A2833D5A9001F51CC /* AboutSwiftcordView.swift */; }; + 3642996A286801C900483D0A /* Guild+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C2A282FA400001F78DF /* Guild+.swift */; }; + 3642996B286801C900483D0A /* ActivitySettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520AD427D4D120009FD740 /* ActivitySettingsView.swift */; }; + 3642996C286801C900483D0A /* MiniUserProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA54D5702841D6CF00B11857 /* MiniUserProfileView.swift */; }; + 3642996D286801C900483D0A /* User+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF5127C8FBB200A9ED72 /* User+.swift */; }; + 3642996E286801C900483D0A /* BillingSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520AD027D4CFCF009FD740 /* BillingSettingsView.swift */; }; + 3642996F286801C900483D0A /* EmbedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2384BE27CCBB26009E15E0 /* EmbedView.swift */; }; + 36429970286801C900483D0A /* Channel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1C28282FA3F7001F78DF /* Channel+.swift */; }; + 36429971286801C900483D0A /* Text+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2BD30D284CCC9800EBB8D6 /* Text+.swift */; }; + 36429972286801C900483D0A /* AppSettingsAppearanceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2BD30B284CB38B00EBB8D6 /* AppSettingsAppearanceView.swift */; }; + 36429973286801C900483D0A /* MessageInfoBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5C2282AA5C700807B54 /* MessageInfoBarView.swift */; }; + 36429974286801C900483D0A /* Message+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF4F27C8D7E000A9ED72 /* Message+.swift */; }; + 36429975286801C900483D0A /* MediaControllerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5C4282AB37500807B54 /* MediaControllerView.swift */; }; + 36429976286801C900483D0A /* Double+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5CB282B879200807B54 /* Double+.swift */; }; + 36429977286801C900483D0A /* MessagesView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA54D57B2845C36E00B11857 /* MessagesView+.swift */; }; + 36429978286801C900483D0A /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520AC827D3A55D009FD740 /* SettingsView.swift */; }; + 36429979286801C900483D0A /* UserAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF2727C633FE00A9ED72 /* UserAvatarView.swift */; }; + 3642997A286801C900483D0A /* View+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA585C9827E1F6AC00FA4EE0 /* View+.swift */; }; + 3642997B286801C900483D0A /* Color+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF4927C8BE8F00A9ED72 /* Color+.swift */; }; + 3642997C286801C900483D0A /* NavigationCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7720CF283F184100D3C335 /* NavigationCommands.swift */; }; + 3642997D286801C900483D0A /* CircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5BB282A570D00807B54 /* CircularProgressView.swift */; }; + 3642997F286801C900483D0A /* AnalyticsWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2BD309284B87AC00EBB8D6 /* AnalyticsWrapper.swift */; }; + 36429980286801C900483D0A /* Int+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA520ADC27D643CE009FD740 /* Int+.swift */; }; + 36429981286801C900483D0A /* AppSettingsAccessibilityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAA22AE284DC0D700C1975E /* AppSettingsAccessibilityView.swift */; }; + 36429982286801C900483D0A /* LottieLoopMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF3127C676FE00A9ED72 /* LottieLoopMode.swift */; }; + 36429983286801C900483D0A /* Logger+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA28027E28095E3000B14E5C /* Logger+.swift */; }; + 36429984286801C900483D0A /* StickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF3327C6861800A9ED72 /* StickerView.swift */; }; + 36429985286801C900483D0A /* ProfileAccentMask.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA54D573284497E400B11857 /* ProfileAccentMask.swift */; }; + 36429986286801C900483D0A /* AudioCenterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAFB5C6282AB56B00807B54 /* AudioCenterManager.swift */; }; + 36429987286801C900483D0A /* LottieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF2927C65D2C00A9ED72 /* LottieView.swift */; }; + 36429988286801C900483D0A /* Date+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF4727C8ABFF00A9ED72 /* Date+.swift */; }; + 36429989286801C900483D0A /* UserSettingsProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA54D5772844DA1400B11857 /* UserSettingsProfileView.swift */; }; + 3642998A286801C900483D0A /* ServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4A892327C5D6C500720909 /* ServerView.swift */; }; + 3642998B286801C900483D0A /* SwiftcordApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4A888727C0AF3000720909 /* SwiftcordApp.swift */; }; + 3642998D286801C900483D0A /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36367144283C19E500A5CBE6 /* AVKit.framework */; }; + 3642998F286801C900483D0A /* CachedAsyncImage in Frameworks */ = {isa = PBXBuildFile; productRef = 36429933286801C900483D0A /* CachedAsyncImage */; }; + 36429991286801C900483D0A /* DiscordKitCommon in Frameworks */ = {isa = PBXBuildFile; productRef = 36429937286801C900483D0A /* DiscordKitCommon */; }; + 36429993286801C900483D0A /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 36429931286801C900483D0A /* Lottie */; }; + 36429994286801C900483D0A /* DiscordKit in Frameworks */ = {isa = PBXBuildFile; productRef = 36429935286801C900483D0A /* DiscordKit */; }; + 36429996286801C900483D0A /* discord-loading-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAAFB5C8282B689000807B54 /* discord-loading-animation.json */; }; + 36429997286801C900483D0A /* GintoMedium.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA2384B927CBC2CE009E15E0 /* GintoMedium.otf */; }; + 36429998286801C900483D0A /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA4A888E27C0AF3200720909 /* Preview Assets.xcassets */; }; + 36429999286801C900483D0A /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 36BC29F2285C162500A8B316 /* Credits.rtf */; }; + 3642999A286801C900483D0A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA2ADF2F2847B13F004A35F2 /* Localizable.strings */; }; + 3642999B286801C900483D0A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA4A888B27C0AF3200720909 /* Assets.xcassets */; }; + 3642999C286801C900483D0A /* GintoBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA2384B827CBC2CE009E15E0 /* GintoBold.otf */; }; + 3642999D286801C900483D0A /* typing-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAE557FA282D00B6001F4EF1 /* typing-animation.json */; }; + 364299A62868042F00483D0A /* AppCenterAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 364299A52868042F00483D0A /* AppCenterAnalytics */; }; + 364299A82868042F00483D0A /* AppCenterCrashes in Frameworks */ = {isa = PBXBuildFile; productRef = 364299A72868042F00483D0A /* AppCenterCrashes */; }; 3684BB59283C696E005045AE /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 3684BB58283C696E005045AE /* Sparkle */; }; 3684BB5B283C69C5005045AE /* Sparkle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3684BB5A283C69C5005045AE /* Sparkle.swift */; }; 36BC29F3285C162500A8B316 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 36BC29F2285C162500A8B316 /* Credits.rtf */; }; @@ -106,6 +198,8 @@ /* Begin PBXFileReference section */ 36004E1C283D63E500F0BA73 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; 36367144283C19E500A5CBE6 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; }; + 364299A3286801C900483D0A /* Swiftcord.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Swiftcord.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 364299AD286804ED00483D0A /* Swiftcord (App Store).plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Swiftcord (App Store).plist"; sourceTree = ""; }; 3684BB5A283C69C5005045AE /* Sparkle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sparkle.swift; sourceTree = ""; }; 36BC29F2285C162500A8B316 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; }; 900F6D9D284A1A92000B6D29 /* Project Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Project Shared.xcconfig"; sourceTree = ""; }; @@ -205,6 +299,20 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 3642998C286801C900483D0A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3642998D286801C900483D0A /* AVKit.framework in Frameworks */, + 3642998F286801C900483D0A /* CachedAsyncImage in Frameworks */, + 364299A62868042F00483D0A /* AppCenterAnalytics in Frameworks */, + 36429991286801C900483D0A /* DiscordKitCommon in Frameworks */, + 36429993286801C900483D0A /* Lottie in Frameworks */, + 36429994286801C900483D0A /* DiscordKit in Frameworks */, + 364299A82868042F00483D0A /* AppCenterCrashes in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA4A888127C0AF3000720909 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -311,6 +419,7 @@ isa = PBXGroup; children = ( DA4A888427C0AF3000720909 /* Swiftcord.app */, + 364299A3286801C900483D0A /* Swiftcord.app */, ); name = Products; sourceTree = ""; @@ -331,6 +440,7 @@ 900F6DA0284A1C0C000B6D29 /* GeneratedBuildSettings.swift */, DA4A889527C0AF3200720909 /* Swiftcord.entitlements */, DA23843827CB934D009E15E0 /* Info.plist */, + 364299AD286804ED00483D0A /* Swiftcord (App Store).plist */, DA2ADF2F2847B13F004A35F2 /* Localizable.strings */, DA4A888B27C0AF3200720909 /* Assets.xcassets */, DA4A888D27C0AF3200720909 /* Preview Content */, @@ -569,6 +679,32 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 36429930286801C900483D0A /* Swiftcord (App Store) */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3642999F286801C900483D0A /* Build configuration list for PBXNativeTarget "Swiftcord (App Store)" */; + buildPhases = ( + 3642993D286801C900483D0A /* Sources */, + 3642998C286801C900483D0A /* Frameworks */, + 36429995286801C900483D0A /* Resources */, + 3642999E286801C900483D0A /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Swiftcord (App Store)"; + packageProductDependencies = ( + 36429931286801C900483D0A /* Lottie */, + 36429933286801C900483D0A /* CachedAsyncImage */, + 36429935286801C900483D0A /* DiscordKit */, + 36429937286801C900483D0A /* DiscordKitCommon */, + 364299A52868042F00483D0A /* AppCenterAnalytics */, + 364299A72868042F00483D0A /* AppCenterCrashes */, + ); + productName = "Native Discord"; + productReference = 364299A3286801C900483D0A /* Swiftcord.app */; + productType = "com.apple.product-type.application"; + }; DA4A888327C0AF3000720909 /* Swiftcord */ = { isa = PBXNativeTarget; buildConfigurationList = DA4A889827C0AF3200720909 /* Build configuration list for PBXNativeTarget "Swiftcord" */; @@ -634,11 +770,27 @@ projectRoot = ""; targets = ( DA4A888327C0AF3000720909 /* Swiftcord */, + 36429930286801C900483D0A /* Swiftcord (App Store) */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 36429995286801C900483D0A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 36429996286801C900483D0A /* discord-loading-animation.json in Resources */, + 36429997286801C900483D0A /* GintoMedium.otf in Resources */, + 36429998286801C900483D0A /* Preview Assets.xcassets in Resources */, + 36429999286801C900483D0A /* Credits.rtf in Resources */, + 3642999A286801C900483D0A /* Localizable.strings in Resources */, + 3642999B286801C900483D0A /* Assets.xcassets in Resources */, + 3642999C286801C900483D0A /* GintoBold.otf in Resources */, + 3642999D286801C900483D0A /* typing-animation.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA4A888227C0AF3000720909 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -674,9 +826,110 @@ shellPath = /bin/sh; shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which swiftlint > /dev/null; then\n swiftlint --config \"$SRCROOT/.swiftlint.yml\"\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; + 3642999E286801C900483D0A /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which swiftlint > /dev/null; then\n swiftlint --config \"$SRCROOT/.swiftlint.yml\"\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 3642993D286801C900483D0A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3642993E286801C900483D0A /* OnboardingView.swift in Sources */, + 3642993F286801C900483D0A /* String+.swift in Sources */, + 36429940286801C900483D0A /* ChannelList.swift in Sources */, + 36429941286801C900483D0A /* ReferenceMessageView.swift in Sources */, + 36429942286801C900483D0A /* MessagesView.swift in Sources */, + 36429943286801C900483D0A /* Cache.swift in Sources */, + 36429944286801C900483D0A /* Keychain.swift in Sources */, + 36429945286801C900483D0A /* AnyTransition+.swift in Sources */, + 36429946286801C900483D0A /* Array.Channel+.swift in Sources */, + 36429947286801C900483D0A /* MergePartialMessage.swift in Sources */, + 36429948286801C900483D0A /* GitHubAPI.swift in Sources */, + 36429949286801C900483D0A /* NSTextView+.swift in Sources */, + 3642994A286801C900483D0A /* GeneratedBuildSettings.swift in Sources */, + 3642994B286801C900483D0A /* WrapperLottieView.swift in Sources */, + 3642994C286801C900483D0A /* AttachmentView.swift in Sources */, + 3642994D286801C900483D0A /* GitHubStructs.swift in Sources */, + 3642994E286801C900483D0A /* Font+.swift in Sources */, + 3642994F286801C900483D0A /* LoFiMessageView.swift in Sources */, + 36429950286801C900483D0A /* CurrentUserFooter.swift in Sources */, + 36429951286801C900483D0A /* TagCloudView.swift in Sources */, + 36429952286801C900483D0A /* Persistence.swift in Sources */, + 36429953286801C900483D0A /* LoadingView.swift in Sources */, + 36429954286801C900483D0A /* CurrentUser+.swift in Sources */, + 36429955286801C900483D0A /* DiscordChannelButton.swift in Sources */, + 36429956286801C900483D0A /* MiscSettingsView.swift in Sources */, + 36429957286801C900483D0A /* MessageInputView.swift in Sources */, + 36429958286801C900483D0A /* AppSettingsView.swift in Sources */, + 36429959286801C900483D0A /* WebView.swift in Sources */, + 3642995A286801C900483D0A /* DebugSettingsView.swift in Sources */, + 3642995B286801C900483D0A /* LoginView.swift in Sources */, + 3642995C286801C900483D0A /* UIStateEnv.swift in Sources */, + 3642995D286801C900483D0A /* MessageView.swift in Sources */, + 3642995E286801C900483D0A /* ContentView.swift in Sources */, + 3642995F286801C900483D0A /* ChannelButton.swift in Sources */, + 36429960286801C900483D0A /* CacheModel.xcdatamodeld in Sources */, + 36429961286801C900483D0A /* UserSettingsAccountView.swift in Sources */, + 36429962286801C900483D0A /* Bool+.swift in Sources */, + 36429963286801C900483D0A /* AppDelegate.swift in Sources */, + 36429964286801C900483D0A /* ServerButton.swift in Sources */, + 36429965286801C900483D0A /* LargeUserProfileView.swift in Sources */, + 36429966286801C900483D0A /* ProfileBadges.swift in Sources */, + 36429967286801C900483D0A /* FlatButtonStyle.swift in Sources */, + 36429968286801C900483D0A /* UserSettingsView.swift in Sources */, + 36429969286801C900483D0A /* AboutSwiftcordView.swift in Sources */, + 3642996A286801C900483D0A /* Guild+.swift in Sources */, + 3642996B286801C900483D0A /* ActivitySettingsView.swift in Sources */, + 3642996C286801C900483D0A /* MiniUserProfileView.swift in Sources */, + 3642996D286801C900483D0A /* User+.swift in Sources */, + 3642996E286801C900483D0A /* BillingSettingsView.swift in Sources */, + 3642996F286801C900483D0A /* EmbedView.swift in Sources */, + 36429970286801C900483D0A /* Channel+.swift in Sources */, + 36429971286801C900483D0A /* Text+.swift in Sources */, + 36429972286801C900483D0A /* AppSettingsAppearanceView.swift in Sources */, + 36429973286801C900483D0A /* MessageInfoBarView.swift in Sources */, + 36429974286801C900483D0A /* Message+.swift in Sources */, + 36429975286801C900483D0A /* MediaControllerView.swift in Sources */, + 36429976286801C900483D0A /* Double+.swift in Sources */, + 36429977286801C900483D0A /* MessagesView+.swift in Sources */, + 36429978286801C900483D0A /* SettingsView.swift in Sources */, + 36429979286801C900483D0A /* UserAvatarView.swift in Sources */, + 3642997A286801C900483D0A /* View+.swift in Sources */, + 3642997B286801C900483D0A /* Color+.swift in Sources */, + 3642997C286801C900483D0A /* NavigationCommands.swift in Sources */, + 3642997D286801C900483D0A /* CircularProgressView.swift in Sources */, + 3642997F286801C900483D0A /* AnalyticsWrapper.swift in Sources */, + 36429980286801C900483D0A /* Int+.swift in Sources */, + 36429981286801C900483D0A /* AppSettingsAccessibilityView.swift in Sources */, + 36429982286801C900483D0A /* LottieLoopMode.swift in Sources */, + 36429983286801C900483D0A /* Logger+.swift in Sources */, + 36429984286801C900483D0A /* StickerView.swift in Sources */, + 36429985286801C900483D0A /* ProfileAccentMask.swift in Sources */, + 36429986286801C900483D0A /* AudioCenterManager.swift in Sources */, + 36429987286801C900483D0A /* LottieView.swift in Sources */, + 36429988286801C900483D0A /* Date+.swift in Sources */, + 36429989286801C900483D0A /* UserSettingsProfileView.swift in Sources */, + 3642998A286801C900483D0A /* ServerView.swift in Sources */, + 3642998B286801C900483D0A /* SwiftcordApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA4A888027C0AF3000720909 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -778,6 +1031,189 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 364298B82867FF8800483D0A /* App Store */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 900F6D9F284A1AE6000B6D29 /* Project Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = "App Store"; + }; + 364298B92867FF8800483D0A /* App Store */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = Swiftcord/Swiftcord.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 8; + DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; + DEVELOPMENT_TEAM = RJNC97Y8QD; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Swiftcord/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; + INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.0; + MARKETING_VERSION = 0.4.1; + PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = APP_STORE; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = "App Store"; + }; + 364299A0286801C900483D0A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = Swiftcord/Swiftcord.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 8; + DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; + DEVELOPMENT_TEAM = RJNC97Y8QD; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "Swiftcord/Swiftcord (App Store).plist"; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; + INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.0; + MARKETING_VERSION = 0.4.1; + PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; + PRODUCT_NAME = Swiftcord; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 364299A1286801C900483D0A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = Swiftcord/Swiftcord.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 8; + DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; + DEVELOPMENT_TEAM = RJNC97Y8QD; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "Swiftcord/Swiftcord (App Store).plist"; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; + INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.0; + MARKETING_VERSION = 0.4.1; + PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; + PRODUCT_NAME = Swiftcord; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 364299A2286801C900483D0A /* App Store */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = Swiftcord/Swiftcord.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 8; + DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; + DEVELOPMENT_TEAM = RJNC97Y8QD; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "Swiftcord/Swiftcord (App Store).plist"; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; + INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.0; + MARKETING_VERSION = 0.4.1; + PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; + PRODUCT_NAME = Swiftcord; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = APP_STORE; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = "App Store"; + }; DA4A889627C0AF3200720909 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 900F6D9E284A1ADE000B6D29 /* Project Debug.xcconfig */; @@ -923,7 +1359,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 12.0; MARKETING_VERSION = 0.4.1; - PRODUCT_BUNDLE_IDENTIFIER = com.cryptoalgo.swiftcord; + PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -954,7 +1390,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 12.0; MARKETING_VERSION = 0.4.1; - PRODUCT_BUNDLE_IDENTIFIER = com.cryptoalgo.swiftcord; + PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -964,11 +1400,22 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 3642999F286801C900483D0A /* Build configuration list for PBXNativeTarget "Swiftcord (App Store)" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 364299A0286801C900483D0A /* Debug */, + 364299A1286801C900483D0A /* Release */, + 364299A2286801C900483D0A /* App Store */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DA4A887F27C0AF3000720909 /* Build configuration list for PBXProject "Swiftcord" */ = { isa = XCConfigurationList; buildConfigurations = ( DA4A889627C0AF3200720909 /* Debug */, DA4A889727C0AF3200720909 /* Release */, + 364298B82867FF8800483D0A /* App Store */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -978,6 +1425,7 @@ buildConfigurations = ( DA4A889927C0AF3200720909 /* Debug */, DA4A889A27C0AF3200720909 /* Release */, + 364298B92867FF8800483D0A /* App Store */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -985,6 +1433,30 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + 36429932286801C900483D0A /* XCRemoteSwiftPackageReference "lottie-ios" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/airbnb/lottie-ios.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 3.3.0; + }; + }; + 36429934286801C900483D0A /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/lorenzofiamingo/swiftui-cached-async-image"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.0.0; + }; + }; + 36429936286801C900483D0A /* XCRemoteSwiftPackageReference "DiscordKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SwiftcordApp/DiscordKit"; + requirement = { + branch = main; + kind = branch; + }; + }; 3684BB57283C696E005045AE /* XCRemoteSwiftPackageReference "Sparkle" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/sparkle-project/Sparkle"; @@ -1028,6 +1500,36 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 36429931286801C900483D0A /* Lottie */ = { + isa = XCSwiftPackageProductDependency; + package = 36429932286801C900483D0A /* XCRemoteSwiftPackageReference "lottie-ios" */; + productName = Lottie; + }; + 36429933286801C900483D0A /* CachedAsyncImage */ = { + isa = XCSwiftPackageProductDependency; + package = 36429934286801C900483D0A /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */; + productName = CachedAsyncImage; + }; + 36429935286801C900483D0A /* DiscordKit */ = { + isa = XCSwiftPackageProductDependency; + package = 36429936286801C900483D0A /* XCRemoteSwiftPackageReference "DiscordKit" */; + productName = DiscordKit; + }; + 36429937286801C900483D0A /* DiscordKitCommon */ = { + isa = XCSwiftPackageProductDependency; + package = 36429936286801C900483D0A /* XCRemoteSwiftPackageReference "DiscordKit" */; + productName = DiscordKitCommon; + }; + 364299A52868042F00483D0A /* AppCenterAnalytics */ = { + isa = XCSwiftPackageProductDependency; + package = DA97BA8E2849F9C500059FD7 /* XCRemoteSwiftPackageReference "appcenter-sdk-apple" */; + productName = AppCenterAnalytics; + }; + 364299A72868042F00483D0A /* AppCenterCrashes */ = { + isa = XCSwiftPackageProductDependency; + package = DA97BA8E2849F9C500059FD7 /* XCRemoteSwiftPackageReference "appcenter-sdk-apple" */; + productName = AppCenterCrashes; + }; 3684BB58283C696E005045AE /* Sparkle */ = { isa = XCSwiftPackageProductDependency; package = 3684BB57283C696E005045AE /* XCRemoteSwiftPackageReference "Sparkle" */; diff --git a/Swiftcord.xcodeproj/xcshareddata/xcschemes/Swiftcord (App Store).xcscheme b/Swiftcord.xcodeproj/xcshareddata/xcschemes/Swiftcord (App Store).xcscheme new file mode 100644 index 00000000..14f13c60 --- /dev/null +++ b/Swiftcord.xcodeproj/xcshareddata/xcschemes/Swiftcord (App Store).xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Swiftcord/Swiftcord (App Store).plist b/Swiftcord/Swiftcord (App Store).plist new file mode 100644 index 00000000..1d3d97f9 --- /dev/null +++ b/Swiftcord/Swiftcord (App Store).plist @@ -0,0 +1,8 @@ + + + + + ATSApplicationFontsPath + . + + diff --git a/Swiftcord/SwiftcordApp.swift b/Swiftcord/SwiftcordApp.swift index 1f185b46..457c06fd 100644 --- a/Swiftcord/SwiftcordApp.swift +++ b/Swiftcord/SwiftcordApp.swift @@ -18,7 +18,9 @@ struct SwiftcordApp: App { // @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate // let persistenceController = PersistenceController.shared + #if !APP_STORE @StateObject var updaterViewModel = UpdaterViewModel() + #endif @StateObject private var gateway = DiscordGateway() @StateObject private var restAPI = DiscordREST() @StateObject private var state = UIState() @@ -55,9 +57,11 @@ struct SwiftcordApp: App { } } .commands { + #if !APP_STORE CommandGroup(after: .appInfo) { CheckForUpdatesView(updaterViewModel: updaterViewModel) } + #endif SidebarCommands() NavigationCommands() From 872586c0a4dc0d1eca7f5467daf756c8a454e2ae Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Sun, 26 Jun 2022 07:55:18 -0400 Subject: [PATCH 29/56] Update Swiftcord (App Store).plist --- Swiftcord/Swiftcord (App Store).plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Swiftcord/Swiftcord (App Store).plist b/Swiftcord/Swiftcord (App Store).plist index 1d3d97f9..d7ea9f14 100644 --- a/Swiftcord/Swiftcord (App Store).plist +++ b/Swiftcord/Swiftcord (App Store).plist @@ -4,5 +4,7 @@ ATSApplicationFontsPath . + key>ITSAppUsesNonExemptEncryption + From d4745734a5e16d8d9710e0d258a6529947e40b0f Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Sun, 26 Jun 2022 07:55:31 -0400 Subject: [PATCH 30/56] Update Swiftcord (App Store).plist --- Swiftcord/Swiftcord (App Store).plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Swiftcord/Swiftcord (App Store).plist b/Swiftcord/Swiftcord (App Store).plist index d7ea9f14..aa31c7a4 100644 --- a/Swiftcord/Swiftcord (App Store).plist +++ b/Swiftcord/Swiftcord (App Store).plist @@ -4,7 +4,7 @@ ATSApplicationFontsPath . - key>ITSAppUsesNonExemptEncryption + ITSAppUsesNonExemptEncryption From 4b4aa65779584c8a37e7b5c0b25e4bb864e5d673 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Mon, 27 Jun 2022 13:57:43 +0000 Subject: [PATCH 31/56] Export appcerter symbols when building with Xcode cloud --- ci_scripts/ci_post_xcodebuild.sh | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 ci_scripts/ci_post_xcodebuild.sh diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh new file mode 100644 index 00000000..2df58eed --- /dev/null +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Upload symbols to App Center + +appcenter crashes upload-symbols \ + --token $APPCENTER_API_TOKEN \ + --app "Swiftcord/Swiftcord" \ + --xcarchive "Swiftcord.xcarchive" \ No newline at end of file From 0ee1d4798293b1606c5dcf094442365c7ab80d37 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Mon, 27 Jun 2022 14:13:16 +0000 Subject: [PATCH 32/56] Install AppCenter CLI --- ci_scripts/ci_post_xcodebuild.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh index 2df58eed..a4a51f59 100644 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -1,7 +1,13 @@ #!/bin/bash -# Upload symbols to App Center +# Install AppCenter-CLI +mkdir -p /Users/local/Homebrew/Cellar/node-16/16/ +curl https://nodejs.org/download/release/latest-gallium/node-v16.15.1-darwin-x64.tar.xz --output node-16.tar.gz +tar -xf node-16.tar.gz -C /Users/local/Homebrew/Cellar/node-16/16/ --strip-components=1 +brew link node-16 +npm install --location=global appcenter-cli +# Upload symbols to App Center appcenter crashes upload-symbols \ --token $APPCENTER_API_TOKEN \ --app "Swiftcord/Swiftcord" \ From 9121c1b3501bc5913db37ccd5b8e5797a2b29791 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Mon, 27 Jun 2022 14:25:53 +0000 Subject: [PATCH 33/56] deal with npm weirdness --- ci_scripts/ci_post_xcodebuild.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh index a4a51f59..90eab030 100644 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -4,11 +4,10 @@ mkdir -p /Users/local/Homebrew/Cellar/node-16/16/ curl https://nodejs.org/download/release/latest-gallium/node-v16.15.1-darwin-x64.tar.xz --output node-16.tar.gz tar -xf node-16.tar.gz -C /Users/local/Homebrew/Cellar/node-16/16/ --strip-components=1 -brew link node-16 -npm install --location=global appcenter-cli +/Users/local/Homebrew/Cellar/node-16/16/bin/npm install appcenter-cli # Upload symbols to App Center -appcenter crashes upload-symbols \ - --token $APPCENTER_API_TOKEN \ +npm exec appcenter crashes upload-symbols \ + --token "$APPCENTER_API_TOKEN" \ --app "Swiftcord/Swiftcord" \ - --xcarchive "Swiftcord.xcarchive" \ No newline at end of file + --xcarchive "$CI_ARCHIVE_PATH" \ No newline at end of file From 1b55322e01054e1115278ec1044993e186c8b578 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Mon, 27 Jun 2022 14:32:07 +0000 Subject: [PATCH 34/56] yet more npm fixes --- ci_scripts/ci_post_xcodebuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh index 90eab030..52967d50 100644 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -7,7 +7,7 @@ tar -xf node-16.tar.gz -C /Users/local/Homebrew/Cellar/node-16/16/ --strip-compo /Users/local/Homebrew/Cellar/node-16/16/bin/npm install appcenter-cli # Upload symbols to App Center -npm exec appcenter crashes upload-symbols \ +/Users/local/Homebrew/Cellar/node-16/16/bin/npm exec appcenter crashes upload-symbols \ --token "$APPCENTER_API_TOKEN" \ --app "Swiftcord/Swiftcord" \ --xcarchive "$CI_ARCHIVE_PATH" \ No newline at end of file From b5e4fb0f877a8acc03aa4253fded0b23f6e7f26a Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Mon, 27 Jun 2022 14:38:39 +0000 Subject: [PATCH 35/56] more CI fixes --- ci_scripts/ci_post_xcodebuild.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh index 52967d50..db67ae74 100644 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -4,10 +4,12 @@ mkdir -p /Users/local/Homebrew/Cellar/node-16/16/ curl https://nodejs.org/download/release/latest-gallium/node-v16.15.1-darwin-x64.tar.xz --output node-16.tar.gz tar -xf node-16.tar.gz -C /Users/local/Homebrew/Cellar/node-16/16/ --strip-components=1 -/Users/local/Homebrew/Cellar/node-16/16/bin/npm install appcenter-cli + +export PATH="/Users/local/Homebrew/Cellar/node-16/16/bin/:$PATH" +npm install appcenter-cli # Upload symbols to App Center -/Users/local/Homebrew/Cellar/node-16/16/bin/npm exec appcenter crashes upload-symbols \ +npm exec appcenter crashes upload-symbols \ --token "$APPCENTER_API_TOKEN" \ --app "Swiftcord/Swiftcord" \ --xcarchive "$CI_ARCHIVE_PATH" \ No newline at end of file From e26195cdda629ee5cfd8083045ce21f48eaf281c Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Mon, 27 Jun 2022 14:53:51 +0000 Subject: [PATCH 36/56] more ci fixes --- ci_scripts/ci_post_xcodebuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh index db67ae74..661ebb42 100644 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -9,7 +9,7 @@ export PATH="/Users/local/Homebrew/Cellar/node-16/16/bin/:$PATH" npm install appcenter-cli # Upload symbols to App Center -npm exec appcenter crashes upload-symbols \ +npm exec -- appcenter crashes upload-symbols \ --token "$APPCENTER_API_TOKEN" \ --app "Swiftcord/Swiftcord" \ --xcarchive "$CI_ARCHIVE_PATH" \ No newline at end of file From 86c4d0141e0a23728d5d3478d34c375851dbe663 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Tue, 28 Jun 2022 20:26:50 -0400 Subject: [PATCH 37/56] Add Token Login --- .../xcschemes/Swiftcord (App Store).xcscheme | 6 +-- Swiftcord/Views/ContentView.swift | 2 +- Swiftcord/Views/LoginView.swift | 46 +++++++++++++++---- Swiftcord/en.lproj/Localizable.strings | 6 +++ 4 files changed, 48 insertions(+), 12 deletions(-) diff --git a/Swiftcord.xcodeproj/xcshareddata/xcschemes/Swiftcord (App Store).xcscheme b/Swiftcord.xcodeproj/xcshareddata/xcschemes/Swiftcord (App Store).xcscheme index 14f13c60..0850d72c 100644 --- a/Swiftcord.xcodeproj/xcshareddata/xcschemes/Swiftcord (App Store).xcscheme +++ b/Swiftcord.xcodeproj/xcshareddata/xcschemes/Swiftcord (App Store).xcscheme @@ -15,7 +15,7 @@ @@ -45,7 +45,7 @@ @@ -62,7 +62,7 @@ diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index 77128915..9995e094 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -161,7 +161,7 @@ struct ContentView: View { skipWhatsNew = true } presentingOnboarding = true - print(whatsNewMarkdown) + print(whatsNewMarkdown ?? "") } } }) diff --git a/Swiftcord/Views/LoginView.swift b/Swiftcord/Views/LoginView.swift index b55cad5e..d8fa4940 100644 --- a/Swiftcord/Views/LoginView.swift +++ b/Swiftcord/Views/LoginView.swift @@ -11,6 +11,9 @@ import DiscordKitCore struct LoginView: View { @StateObject var loginWVModel: WebViewModel = WebViewModel(link: "https://canary.discord.com/login") + @State var tokenView: Bool = false + @State var tokenCount = 0 + @State var tokenString: String = "" @EnvironmentObject var gateway: DiscordGateway @EnvironmentObject var restAPI: DiscordREST @@ -18,15 +21,42 @@ struct LoginView: View { var body: some View { ZStack { - WebView() - .environmentObject(loginWVModel) + if !tokenView { + WebView() + .environmentObject(loginWVModel) - if !loginWVModel.didFinishLoading { - ZStack { - ProgressView("Loading Discord login...") - .controlSize(.large) - .frame(maxWidth: .infinity, maxHeight: .infinity) - }.background(.background) + if !loginWVModel.didFinishLoading { + ZStack { + ProgressView("Loading Discord login...") + .controlSize(.large) + .frame(maxWidth: .infinity, maxHeight: .infinity) + }.background(.background) + } + } + + Button("Token Login") { + tokenCount += 1 + if tokenCount >= 5 { + tokenView = !tokenView + } + } + .keyboardShortcut("t", modifiers: [.command, .shift]) + .hidden() + + if tokenView { + VStack { + Text("login.token.title") + .font(.title) + SecureField("login.token.input", text: $tokenString) + HStack { + Button("login.token.back") { + tokenView = !tokenView + } + Button("login.token.login") { + loginWVModel.token = tokenString + } + } + }.padding() } } .frame(minWidth: 850, idealWidth: 950, minHeight: 500, idealHeight: 620) diff --git a/Swiftcord/en.lproj/Localizable.strings b/Swiftcord/en.lproj/Localizable.strings index dca98943..2ccb1c99 100644 --- a/Swiftcord/en.lproj/Localizable.strings +++ b/Swiftcord/en.lproj/Localizable.strings @@ -17,6 +17,12 @@ "onboarding.footer" = "Swiftcord is alpha software, with limitations and bugs. It currently isn't intended to replace the official client, but hopes to someday."; +/* ====== Login ====== */ +"login.token.title" = "Welcome to the secret token login screen!"; +"login.token.input" = "Paste your Discord token here"; +"login.token.back" = "Wait go back"; +"login.token.login" = "Login"; + /* ====== Loading Cover ====== */ "loader.tip.header" = "Did You Know"; From f6000a841c0024e6b02f10732e5c948453d43318 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Tue, 28 Jun 2022 20:27:14 -0400 Subject: [PATCH 38/56] Add panic logout --- Swiftcord/Views/LoadingView.swift | 68 +++++++++++++++++++++++--- Swiftcord/en.lproj/Localizable.strings | 1 + 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/Swiftcord/Views/LoadingView.swift b/Swiftcord/Views/LoadingView.swift index 95ebe7a9..81238477 100644 --- a/Swiftcord/Views/LoadingView.swift +++ b/Swiftcord/Views/LoadingView.swift @@ -6,9 +6,37 @@ // import SwiftUI +import DiscordKit +import DiscordKitCore struct LoadingView: View { @EnvironmentObject var state: UIState + @EnvironmentObject var gateway: DiscordGateway + @EnvironmentObject var restAPI: DiscordREST + + let keyPrefixesToRemove = [ + "lastCh.", + "local.", + "lastSelectedGuild", + "showSendBtn", + "stickerAlwaysAnim", + "theme", + "ttsRate" + ] + + private func logOut() { + for key in UserDefaults.standard.dictionaryRepresentation().keys { + for toRemove in keyPrefixesToRemove { + if key.prefix(toRemove.count) == toRemove { + UserDefaults.standard.removeObject(forKey: key) + break + } + } + } + gateway.logout() + Task { await restAPI.logOut() } + Keychain.remove(key: SwiftcordApp.tokenKeychainKey) + } @Environment(\.colorScheme) private var colorScheme @@ -43,6 +71,7 @@ struct LoadingView: View { ] @State private var displayedTip = "" + @State private var showLogoutButton: Bool = false var body: some View { let loading = state.loadingState != .messageLoad @@ -58,14 +87,37 @@ struct LoadingView: View { .lottieLoopMode(.loop) .if(colorScheme == .light) { view in view.colorInvert() } - Text("loader.tip.header").font(.headline).textCase(.uppercase) - Text(.init(displayedTip)) - .multilineTextAlignment(.center) - .padding(.top, 8) - .frame(maxWidth: 320) - .onAppear { - displayedTip = loadingTips.randomElement()! // Will never be nil because loadingTips can never be empty - } + if Int.random(in: 0..<1000000000) != 0 { + Text("loader.tip.header").font(.headline).textCase(.uppercase) + Text(.init(displayedTip)) + .multilineTextAlignment(.center) + .padding(.top, 8) + .frame(maxWidth: 320) + .onAppear { + displayedTip = loadingTips.randomElement()! // Will never be nil because loadingTips can never be empty + DispatchQueue.main.asyncAfter(deadline: .now() + 15) { + withAnimation { + showLogoutButton = true + } + } + } + } else { + Text("Please wait warmly...").font(.headline) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 15) { + withAnimation { + showLogoutButton = true + } + } + } + } + + if showLogoutButton { + Button("loader.panic.logout") { + logOut() + state.attemptLogin = true + }.padding() + } } .ignoresSafeArea() .frame(maxWidth: .infinity, maxHeight: .infinity) diff --git a/Swiftcord/en.lproj/Localizable.strings b/Swiftcord/en.lproj/Localizable.strings index 2ccb1c99..80fe4bed 100644 --- a/Swiftcord/en.lproj/Localizable.strings +++ b/Swiftcord/en.lproj/Localizable.strings @@ -25,6 +25,7 @@ /* ====== Loading Cover ====== */ "loader.tip.header" = "Did You Know"; +"loader.panic.logout" = "This is taking a while, want to logout?"; /* ====== User ====== */ "user.bio" = "About Me"; From 05d8ee4cb75f305ea0ea8795f13f844f8ede214e Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Tue, 28 Jun 2022 21:07:13 -0400 Subject: [PATCH 39/56] Add Network is Unreachable notice --- Swiftcord.xcodeproj/project.pbxproj | 18 -------------- Swiftcord/Views/LoadingView.swift | 37 +++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index fa36d8d2..3026ed3b 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -686,7 +686,6 @@ 3642993D286801C900483D0A /* Sources */, 3642998C286801C900483D0A /* Frameworks */, 36429995286801C900483D0A /* Resources */, - 3642999E286801C900483D0A /* ShellScript */, ); buildRules = ( ); @@ -826,23 +825,6 @@ shellPath = /bin/sh; shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which swiftlint > /dev/null; then\n swiftlint --config \"$SRCROOT/.swiftlint.yml\"\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; - 3642999E286801C900483D0A /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which swiftlint > /dev/null; then\n swiftlint --config \"$SRCROOT/.swiftlint.yml\"\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/Swiftcord/Views/LoadingView.swift b/Swiftcord/Views/LoadingView.swift index 81238477..055260e0 100644 --- a/Swiftcord/Views/LoadingView.swift +++ b/Swiftcord/Views/LoadingView.swift @@ -8,6 +8,7 @@ import SwiftUI import DiscordKit import DiscordKitCore +import Reachability struct LoadingView: View { @EnvironmentObject var state: UIState @@ -71,7 +72,8 @@ struct LoadingView: View { ] @State private var displayedTip = "" - @State private var showLogoutButton: Bool = false + @State private var showLogoutButton = false + @State private var showNoInternet = false var body: some View { let loading = state.loadingState != .messageLoad @@ -95,18 +97,29 @@ struct LoadingView: View { .frame(maxWidth: 320) .onAppear { displayedTip = loadingTips.randomElement()! // Will never be nil because loadingTips can never be empty - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { - withAnimation { - showLogoutButton = true + + withAnimation { + let connection = try? Reachability(hostname: "https://discord.com/").connection + if connection == .unavailable { + showNoInternet = true + } else { + DispatchQueue.main.asyncAfter(deadline: .now() + 15) { + showLogoutButton = true + } } } } } else { Text("Please wait warmly...").font(.headline) .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { - withAnimation { - showLogoutButton = true + withAnimation { + let connection = try? Reachability(hostname: "https://discord.com/").connection + if connection == .unavailable { + showNoInternet = true + } else { + DispatchQueue.main.asyncAfter(deadline: .now() + 15) { + showLogoutButton = true + } } } } @@ -118,6 +131,16 @@ struct LoadingView: View { state.attemptLogin = true }.padding() } + + if showNoInternet { + if loading { + Text("\(Image(systemName: "bolt.horizontal.fill")) No Network Connectivity") + .font(.headline) + .foregroundColor(.red) + .padding(.top) + Link("Check Discord Status", destination: URL(string: "https://discordstatus.com")!) + } + } } .ignoresSafeArea() .frame(maxWidth: .infinity, maxHeight: .infinity) From a447f96768ca0f0e35719243dea45f9ef26f90cc Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Wed, 29 Jun 2022 13:51:10 +0000 Subject: [PATCH 40/56] make the ci scripts executable --- ci_scripts/ci_post_clone.sh | 10 ++++++++++ ci_scripts/ci_post_xcodebuild.sh | 6 ------ 2 files changed, 10 insertions(+), 6 deletions(-) create mode 100755 ci_scripts/ci_post_clone.sh mode change 100644 => 100755 ci_scripts/ci_post_xcodebuild.sh diff --git a/ci_scripts/ci_post_clone.sh b/ci_scripts/ci_post_clone.sh new file mode 100755 index 00000000..c499b89f --- /dev/null +++ b/ci_scripts/ci_post_clone.sh @@ -0,0 +1,10 @@ +!#/bin/bash + +# Install AppCenter-CLI +mkdir -p /Users/local/Homebrew/Cellar/node-16/16/ +curl https://nodejs.org/download/release/latest-gallium/node-v16.15.1-darwin-x64.tar.xz --output node-16.tar.gz +tar -xf node-16.tar.gz -C /Users/local/Homebrew/Cellar/node-16/16/ --strip-components=1 + +brew link node-16 + +brew install swiftlint \ No newline at end of file diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh old mode 100644 new mode 100755 index 661ebb42..6d781867 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -1,11 +1,5 @@ #!/bin/bash -# Install AppCenter-CLI -mkdir -p /Users/local/Homebrew/Cellar/node-16/16/ -curl https://nodejs.org/download/release/latest-gallium/node-v16.15.1-darwin-x64.tar.xz --output node-16.tar.gz -tar -xf node-16.tar.gz -C /Users/local/Homebrew/Cellar/node-16/16/ --strip-components=1 - -export PATH="/Users/local/Homebrew/Cellar/node-16/16/bin/:$PATH" npm install appcenter-cli # Upload symbols to App Center From 350b09fe88a955d51e378dbcb346e572aca81921 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Wed, 29 Jun 2022 14:42:15 +0000 Subject: [PATCH 41/56] fix shebang in ci_post_clone --- ci_scripts/ci_post_xcodebuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh index 6d781867..aa794c51 100755 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -1,4 +1,4 @@ -#!/bin/bash +!#/bin/bash npm install appcenter-cli From 36f594863e958e40cc97a214186cef0cda7c611e Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Wed, 29 Jun 2022 14:43:34 +0000 Subject: [PATCH 42/56] fix shebangs in scripts --- ci_scripts/ci_post_clone.sh | 2 +- ci_scripts/ci_post_xcodebuild.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci_scripts/ci_post_clone.sh b/ci_scripts/ci_post_clone.sh index c499b89f..cb342983 100755 --- a/ci_scripts/ci_post_clone.sh +++ b/ci_scripts/ci_post_clone.sh @@ -1,4 +1,4 @@ -!#/bin/bash +#!/bin/bash # Install AppCenter-CLI mkdir -p /Users/local/Homebrew/Cellar/node-16/16/ diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh index aa794c51..6d781867 100755 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -1,4 +1,4 @@ -!#/bin/bash +#!/bin/bash npm install appcenter-cli From 0288231bb460629ec4eb29cc6090922095e9d583 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Wed, 29 Jun 2022 21:19:18 -0400 Subject: [PATCH 43/56] =?UTF-8?q?Bottom=20Align=20=E2=80=9CNo=20internet?= =?UTF-8?q?=E2=80=9D=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Swiftcord/Views/LoadingView.swift | 104 ++++++++++++++++-------------- Swiftcord/Views/LoginView.swift | 18 +++--- 2 files changed, 64 insertions(+), 58 deletions(-) diff --git a/Swiftcord/Views/LoadingView.swift b/Swiftcord/Views/LoadingView.swift index 055260e0..7094d5a8 100644 --- a/Swiftcord/Views/LoadingView.swift +++ b/Swiftcord/Views/LoadingView.swift @@ -39,6 +39,8 @@ struct LoadingView: View { Keychain.remove(key: SwiftcordApp.tokenKeychainKey) } + let reach = try? Reachability(hostname: "odin.cs.uga.edu") + @Environment(\.colorScheme) private var colorScheme private let loadingTips = [ @@ -78,70 +80,63 @@ struct LoadingView: View { var body: some View { let loading = state.loadingState != .messageLoad - VStack(spacing: 4) { - LottieView( - name: "discord-loading-animation", - play: .constant(loading), - width: 280, - height: 280 - ) - .frame(width: 280, height: 150) - .lottieLoopMode(.loop) - .if(colorScheme == .light) { view in view.colorInvert() } - - if Int.random(in: 0..<1000000000) != 0 { - Text("loader.tip.header").font(.headline).textCase(.uppercase) - Text(.init(displayedTip)) - .multilineTextAlignment(.center) - .padding(.top, 8) - .frame(maxWidth: 320) - .onAppear { - displayedTip = loadingTips.randomElement()! // Will never be nil because loadingTips can never be empty + ZStack { + VStack(spacing: 4) { + LottieView( + name: "discord-loading-animation", + play: .constant(loading), + width: 280, + height: 280 + ) + .frame(width: 280, height: 150) + .lottieLoopMode(.loop) + .if(colorScheme == .light) { view in view.colorInvert() } - withAnimation { - let connection = try? Reachability(hostname: "https://discord.com/").connection - if connection == .unavailable { - showNoInternet = true - } else { + if Int.random(in: 0..<1000000000) != 0 { + Text("loader.tip.header").font(.headline).textCase(.uppercase) + Text(.init(displayedTip)) + .multilineTextAlignment(.center) + .padding(.top, 8) + .frame(maxWidth: 320) + .onAppear { + displayedTip = loadingTips.randomElement()! // Will never be nil because loadingTips can never be empty + withAnimation { DispatchQueue.main.asyncAfter(deadline: .now() + 15) { showLogoutButton = true } } } - } - } else { - Text("Please wait warmly...").font(.headline) - .onAppear { - withAnimation { - let connection = try? Reachability(hostname: "https://discord.com/").connection - if connection == .unavailable { - showNoInternet = true - } else { + } else { + Text("Please wait warmly...").font(.headline) + .onAppear { + withAnimation { DispatchQueue.main.asyncAfter(deadline: .now() + 15) { showLogoutButton = true } } } - } - } - - if showLogoutButton { - Button("loader.panic.logout") { - logOut() - state.attemptLogin = true - }.padding() + } } - if showNoInternet { - if loading { - Text("\(Image(systemName: "bolt.horizontal.fill")) No Network Connectivity") - .font(.headline) - .foregroundColor(.red) - .padding(.top) - Link("Check Discord Status", destination: URL(string: "https://discordstatus.com")!) + VStack { + if showLogoutButton { + if !showNoInternet { + Button("loader.panic.logout") { + logOut() + state.attemptLogin = true + }.padding() + } + } + if showNoInternet { + Text("\(Image(systemName: "bolt.horizontal.fill")) No Network Connectivity") + .font(.headline) + .foregroundColor(.red) + Link("Check Discord Status", destination: URL(string: "https://discordstatus.com")!) } } - } + .frame(maxHeight: .infinity, alignment: .bottom) + .padding() + } .ignoresSafeArea() .frame(maxWidth: .infinity, maxHeight: .infinity) .allowsHitTesting(loading) @@ -149,6 +144,17 @@ struct LoadingView: View { .opacity(loading ? 1 : 0) .scaleEffect(loading ? 1 : 2) .animation(.interpolatingSpring(stiffness: 200, damping: 120), value: loading) + .onAppear { + reach?.whenUnreachable = { _ in + showNoInternet = true + } + + do { + try reach?.startNotifier() + } catch { + print("Unable to start notifier") + } + } } } diff --git a/Swiftcord/Views/LoginView.swift b/Swiftcord/Views/LoginView.swift index d8fa4940..1673e4e1 100644 --- a/Swiftcord/Views/LoginView.swift +++ b/Swiftcord/Views/LoginView.swift @@ -34,15 +34,6 @@ struct LoginView: View { } } - Button("Token Login") { - tokenCount += 1 - if tokenCount >= 5 { - tokenView = !tokenView - } - } - .keyboardShortcut("t", modifiers: [.command, .shift]) - .hidden() - if tokenView { VStack { Text("login.token.title") @@ -58,6 +49,15 @@ struct LoginView: View { } }.padding() } + + Button("Token Login") { + tokenCount += 1 + if tokenCount >= 5 { + tokenView = !tokenView + } + } + .keyboardShortcut("t", modifiers: [.command, .shift]) + .hidden() } .frame(minWidth: 850, idealWidth: 950, minHeight: 500, idealHeight: 620) .navigationTitle("Login") From f0c4475348691363eeaf3f4c0cee2d07eb2d84aa Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Wed, 29 Jun 2022 22:41:02 -0400 Subject: [PATCH 44/56] Navigation Keybinds now work as intended --- Swiftcord.xcodeproj/project.pbxproj | 6 ++ Swiftcord/Commands/NavigationCommands.swift | 66 +++++++++++++++++---- Swiftcord/SwiftcordApp.swift | 2 +- Swiftcord/Utils/Extensions/Array+.swift | 38 ++++++++++++ Swiftcord/Views/ContentView.swift | 19 +++--- Swiftcord/Views/EnvObjects/UIStateEnv.swift | 3 + Swiftcord/Views/LoginView.swift | 2 +- Swiftcord/Views/Server/ServerView.swift | 2 +- 8 files changed, 113 insertions(+), 25 deletions(-) create mode 100644 Swiftcord/Utils/Extensions/Array+.swift diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 3026ed3b..92298425 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -100,6 +100,8 @@ 3642999D286801C900483D0A /* typing-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAE557FA282D00B6001F4EF1 /* typing-animation.json */; }; 364299A62868042F00483D0A /* AppCenterAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 364299A52868042F00483D0A /* AppCenterAnalytics */; }; 364299A82868042F00483D0A /* AppCenterCrashes in Frameworks */ = {isa = PBXBuildFile; productRef = 364299A72868042F00483D0A /* AppCenterCrashes */; }; + 366BAA8C286D322600B662EA /* Array+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366BAA8B286D322600B662EA /* Array+.swift */; }; + 366BAA8D286D322600B662EA /* Array+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366BAA8B286D322600B662EA /* Array+.swift */; }; 3684BB59283C696E005045AE /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 3684BB58283C696E005045AE /* Sparkle */; }; 3684BB5B283C69C5005045AE /* Sparkle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3684BB5A283C69C5005045AE /* Sparkle.swift */; }; 36BC29F3285C162500A8B316 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 36BC29F2285C162500A8B316 /* Credits.rtf */; }; @@ -200,6 +202,7 @@ 36367144283C19E500A5CBE6 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; }; 364299A3286801C900483D0A /* Swiftcord.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Swiftcord.app; sourceTree = BUILT_PRODUCTS_DIR; }; 364299AD286804ED00483D0A /* Swiftcord (App Store).plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Swiftcord (App Store).plist"; sourceTree = ""; }; + 366BAA8B286D322600B662EA /* Array+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+.swift"; sourceTree = ""; }; 3684BB5A283C69C5005045AE /* Sparkle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sparkle.swift; sourceTree = ""; }; 36BC29F2285C162500A8B316 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; }; 900F6D9D284A1A92000B6D29 /* Project Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Project Shared.xcconfig"; sourceTree = ""; }; @@ -538,6 +541,7 @@ DA54D57B2845C36E00B11857 /* MessagesView+.swift */, DA2BD30D284CCC9800EBB8D6 /* Text+.swift */, DAB5366F285B693700DD9857 /* AnyTransition+.swift */, + 366BAA8B286D322600B662EA /* Array+.swift */, ); path = Extensions; sourceTree = ""; @@ -845,6 +849,7 @@ 36429948286801C900483D0A /* GitHubAPI.swift in Sources */, 36429949286801C900483D0A /* NSTextView+.swift in Sources */, 3642994A286801C900483D0A /* GeneratedBuildSettings.swift in Sources */, + 366BAA8D286D322600B662EA /* Array+.swift in Sources */, 3642994B286801C900483D0A /* WrapperLottieView.swift in Sources */, 3642994C286801C900483D0A /* AttachmentView.swift in Sources */, 3642994D286801C900483D0A /* GitHubStructs.swift in Sources */, @@ -973,6 +978,7 @@ DA32EF5027C8D7E000A9ED72 /* Message+.swift in Sources */, DAAFB5C5282AB37500807B54 /* MediaControllerView.swift in Sources */, DAAFB5CC282B879200807B54 /* Double+.swift in Sources */, + 366BAA8C286D322600B662EA /* Array+.swift in Sources */, DA54D57C2845C36E00B11857 /* MessagesView+.swift in Sources */, DA520AC927D3A55D009FD740 /* SettingsView.swift in Sources */, DA32EF2827C633FE00A9ED72 /* UserAvatarView.swift in Sources */, diff --git a/Swiftcord/Commands/NavigationCommands.swift b/Swiftcord/Commands/NavigationCommands.swift index 291001f2..7fa81ed0 100644 --- a/Swiftcord/Commands/NavigationCommands.swift +++ b/Swiftcord/Commands/NavigationCommands.swift @@ -6,28 +6,70 @@ // import SwiftUI +import DiscordKit struct NavigationCommands: Commands { + @ObservedObject var state: UIState + @ObservedObject var gateway: DiscordGateway + var body: some Commands { CommandMenu("Navigation") { - Button("Previous Server") {} - .keyboardShortcut(.upArrow, modifiers: [.command, .option]) - Button("Next Server") {} - .keyboardShortcut(.downArrow, modifiers: [.command, .option]) + Button("Previous Server") { + let guilds = (gateway.cache.guilds.values.filter({ + !(gateway.cache.userSettings?.guild_positions ?? []).contains($0.id) + }).sorted(by: { lhs, rhs in lhs.joined_at! > rhs.joined_at! })) + + (gateway.cache.userSettings?.guild_positions ?? []) + .compactMap({ gateway.cache.guilds[$0] }) + + guard let previousGuild = guilds.before(state.serverCtx.guild!, loop: true) else { return } + + state.selectedGuildID = previousGuild.id + }.keyboardShortcut(.upArrow, modifiers: [.command, .option]) + + Button("Next Server") { + let guilds = (gateway.cache.guilds.values.filter({ + !(gateway.cache.userSettings?.guild_positions ?? []).contains($0.id) + }).sorted(by: { lhs, rhs in lhs.joined_at! > rhs.joined_at! })) + + (gateway.cache.userSettings?.guild_positions ?? []) + .compactMap({ gateway.cache.guilds[$0] }) + + guard let nextGuild = guilds.after(state.serverCtx.guild!, loop: true) else { return } + + state.selectedGuildID = nextGuild.id + }.keyboardShortcut(.downArrow, modifiers: [.command, .option]) Divider() - Button("Previous Channel") {} - .keyboardShortcut(.upArrow, modifiers: [.option]) - Button("Next Channel") {} - .keyboardShortcut(.downArrow, modifiers: [.option]) + Button("Previous Channel") { + if let channels = state.serverCtx.guild?.channels { + let filteredChannels = channels.filter { $0.type != .category && $0.type != .voice } + let sortedChannels = filteredChannels.discordSorted() + + guard let previousChannel = sortedChannels.before(state.serverCtx.channel!, loop: true) else { return } + + state.serverCtx.channel = previousChannel + } + }.keyboardShortcut(.upArrow, modifiers: [.option]) + + Button("Next Channel") { + if let channels = state.serverCtx.guild?.channels { + let filteredChannels = channels.filter { $0.type != .category && $0.type != .voice } + let sortedChannels = filteredChannels.discordSorted() + + guard let nextChannel = sortedChannels.after(state.serverCtx.channel!, loop: true) else { return } + + state.serverCtx.channel = nextChannel + } + }.keyboardShortcut(.downArrow, modifiers: [.option]) Divider() - Button("DMs") {} - .keyboardShortcut(.rightArrow, modifiers: [.command, .option]) - Button("Create/Join Server") {} - .keyboardShortcut("N", modifiers: [.command, .shift]) + Button("DMs") { + state.selectedGuildID = "@me" + }.keyboardShortcut(.rightArrow, modifiers: [.command, .option]) + +// Button("Create/Join Server") {} +// .keyboardShortcut("N", modifiers: [.command, .shift]) } } } diff --git a/Swiftcord/SwiftcordApp.swift b/Swiftcord/SwiftcordApp.swift index 457c06fd..a0f0dad6 100644 --- a/Swiftcord/SwiftcordApp.swift +++ b/Swiftcord/SwiftcordApp.swift @@ -64,7 +64,7 @@ struct SwiftcordApp: App { #endif SidebarCommands() - NavigationCommands() + NavigationCommands(state: state, gateway: gateway) } Settings { diff --git a/Swiftcord/Utils/Extensions/Array+.swift b/Swiftcord/Utils/Extensions/Array+.swift new file mode 100644 index 00000000..df310a18 --- /dev/null +++ b/Swiftcord/Utils/Extensions/Array+.swift @@ -0,0 +1,38 @@ +// +// Array+.swift +// Swiftcord +// +// Created by Andrew Glaze on 6/29/22. +// + +extension BidirectionalCollection where Iterator.Element: Equatable { + typealias Element = Self.Iterator.Element + + func after(_ item: Element, loop: Bool = false) -> Element? { + if let itemIndex = self.firstIndex(of: item) { + let lastItem: Bool = (index(after: itemIndex) == endIndex) + if loop && lastItem { + return self.first + } else if lastItem { + return nil + } else { + return self[index(after: itemIndex)] + } + } + return nil + } + + func before(_ item: Element, loop: Bool = false) -> Element? { + if let itemIndex = self.firstIndex(of: item) { + let firstItem: Bool = (itemIndex == startIndex) + if loop && firstItem { + return self.last + } else if firstItem { + return nil + } else { + return self[index(before: itemIndex)] + } + } + return nil + } +} diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index 9995e094..6d30023d 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -27,7 +27,6 @@ struct ContentView: View { private var items: FetchedResults*/ @State private var sheetOpen = false - @State private var selectedGuildID: Snowflake? @State private var loadingGuildID: Snowflake? @State private var presentingOnboarding = false @State private var skipWhatsNew = false @@ -65,8 +64,8 @@ struct ContentView: View { private func loadLastSelectedGuild() { if let lGID = UserDefaults.standard.string(forKey: "lastSelectedGuild"), gateway.cache.guilds[lGID] != nil || lGID == "@me" { - selectedGuildID = lGID - } else { selectedGuildID = "@me" } + state.selectedGuildID = lGID + } else { state.selectedGuildID = "@me" } } var body: some View { @@ -74,10 +73,10 @@ struct ContentView: View { ScrollView(showsIndicators: false) { LazyVStack(spacing: 8) { ServerButton( - selected: selectedGuildID == "@me", + selected: state.selectedGuildID == "@me", name: "Home", assetIconName: "DiscordIcon", - onSelect: { selectedGuildID = "@me" } + onSelect: { state.selectedGuildID = "@me" } ).padding(.top, 4) CustomHorizontalDivider().frame(width: 32, height: 1) @@ -90,11 +89,11 @@ struct ContentView: View { .compactMap({ gateway.cache.guilds[$0] }) ) { guild in ServerButton( - selected: selectedGuildID == guild.id || loadingGuildID == guild.id, + selected: state.selectedGuildID == guild.id || loadingGuildID == guild.id, name: guild.name, serverIconURL: guild.icon != nil ? "\(GatewayConfig.default.cdnURL)icons/\(guild.id)/\(guild.icon!).webp?size=240" : nil, isLoading: loadingGuildID == guild.id, - onSelect: { selectedGuildID = guild.id } + onSelect: { state.selectedGuildID = guild.id } ) } @@ -137,13 +136,13 @@ struct ContentView: View { } ServerView( - guild: selectedGuildID == nil + guild: state.selectedGuildID == nil ? nil - : (selectedGuildID == "@me" ? makeDMGuild() : gateway.cache.guilds[selectedGuildID!]) + : (state.selectedGuildID == "@me" ? makeDMGuild() : gateway.cache.guilds[state.selectedGuildID!]), serverCtx: state.serverCtx ) } .environmentObject(audioManager) - .onChange(of: selectedGuildID) { id in + .onChange(of: state.selectedGuildID) { id in guard let id = id else { return } UserDefaults.standard.set(id.description, forKey: "lastSelectedGuild") } diff --git a/Swiftcord/Views/EnvObjects/UIStateEnv.swift b/Swiftcord/Views/EnvObjects/UIStateEnv.swift index 6715335e..33411be8 100644 --- a/Swiftcord/Views/EnvObjects/UIStateEnv.swift +++ b/Swiftcord/Views/EnvObjects/UIStateEnv.swift @@ -6,6 +6,7 @@ // import Foundation +import DiscordKitCommon enum LoadingState { case initial @@ -18,4 +19,6 @@ class UIState: ObservableObject { @Published var attemptLogin = false @Published var selfMute = false @Published var selfDeaf = false + @Published var serverCtx = ServerContext() + @Published var selectedGuildID: Snowflake? } diff --git a/Swiftcord/Views/LoginView.swift b/Swiftcord/Views/LoginView.swift index 1673e4e1..254b2a4d 100644 --- a/Swiftcord/Views/LoginView.swift +++ b/Swiftcord/Views/LoginView.swift @@ -49,7 +49,7 @@ struct LoginView: View { } }.padding() } - + Button("Token Login") { tokenCount += 1 if tokenCount >= 5 { diff --git a/Swiftcord/Views/Server/ServerView.swift b/Swiftcord/Views/Server/ServerView.swift index 00864d00..1277a108 100644 --- a/Swiftcord/Views/Server/ServerView.swift +++ b/Swiftcord/Views/Server/ServerView.swift @@ -27,7 +27,7 @@ struct ServerView: View { @EnvironmentObject var restAPI: DiscordREST @EnvironmentObject var audioManager: AudioCenterManager - @StateObject private var serverCtx = ServerContext() + @StateObject var serverCtx: ServerContext private func loadChannels() { guard let channels = serverCtx.guild?.channels?.discordSorted() From bff4bb18c3f1c0adf953a4a67ac3b640b996abab Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Fri, 1 Jul 2022 16:55:49 -0400 Subject: [PATCH 45/56] =?UTF-8?q?Fix=20navigation=20channel=20sorting,=20j?= =?UTF-8?q?ump=20to=20DMs=20now=20behaves=20exactly=20like=20discord?= =?UTF-8?q?=E2=80=99s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Swiftcord/Commands/NavigationCommands.swift | 36 +++++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/Swiftcord/Commands/NavigationCommands.swift b/Swiftcord/Commands/NavigationCommands.swift index 7fa81ed0..dac53338 100644 --- a/Swiftcord/Commands/NavigationCommands.swift +++ b/Swiftcord/Commands/NavigationCommands.swift @@ -7,12 +7,14 @@ import SwiftUI import DiscordKit +import DiscordKitCommon struct NavigationCommands: Commands { @ObservedObject var state: UIState @ObservedObject var gateway: DiscordGateway + @State var previousServer: Snowflake? - var body: some Commands { + var body: some Commands { CommandMenu("Navigation") { Button("Previous Server") { let guilds = (gateway.cache.guilds.values.filter({ @@ -42,8 +44,7 @@ struct NavigationCommands: Commands { Button("Previous Channel") { if let channels = state.serverCtx.guild?.channels { - let filteredChannels = channels.filter { $0.type != .category && $0.type != .voice } - let sortedChannels = filteredChannels.discordSorted() + let sortedChannels = sortChannels(channels) guard let previousChannel = sortedChannels.before(state.serverCtx.channel!, loop: true) else { return } @@ -53,8 +54,7 @@ struct NavigationCommands: Commands { Button("Next Channel") { if let channels = state.serverCtx.guild?.channels { - let filteredChannels = channels.filter { $0.type != .category && $0.type != .voice } - let sortedChannels = filteredChannels.discordSorted() + let sortedChannels = sortChannels(channels) guard let nextChannel = sortedChannels.after(state.serverCtx.channel!, loop: true) else { return } @@ -65,11 +65,33 @@ struct NavigationCommands: Commands { Divider() Button("DMs") { - state.selectedGuildID = "@me" + if state.selectedGuildID != "@me" { + previousServer = state.selectedGuildID + state.selectedGuildID = "@me" + } else { + if previousServer != nil { + state.selectedGuildID = previousServer + } + } }.keyboardShortcut(.rightArrow, modifiers: [.command, .option]) // Button("Create/Join Server") {} // .keyboardShortcut("N", modifiers: [.command, .shift]) } - } + } + + func sortChannels(_ channels: [Channel]) -> [Channel] { + let filteredChannels = channels.filter { $0.parent_id == nil && $0.type != .category && $0.type != .voice } + var sortedChannels = filteredChannels + + let categories = channels + .filter { $0.parent_id == nil && $0.type == .category } + .discordSorted() + for category in categories { + let categoryChannels = channels.filter({ $0.parent_id == category.id && $0.type != .voice }).discordSorted() + sortedChannels.append(contentsOf: categoryChannels) + } + + return sortedChannels + } } From f231ce01aa8ad50f4f0e728301516993d8ca54f5 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Fri, 1 Jul 2022 17:59:22 -0400 Subject: [PATCH 46/56] Added option to hide NSFW channels --- Swiftcord.xcodeproj/project.pbxproj | 6 ++++ Swiftcord/Commands/NavigationCommands.swift | 19 ++++++++++-- Swiftcord/Views/Server/ChannelList.swift | 29 ++++++++++++++----- .../User/UserSettingsPrivacySafetyView.swift | 18 ++++++++++++ .../Settings/User/UserSettingsView.swift | 2 +- 5 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 Swiftcord/Views/Settings/User/UserSettingsPrivacySafetyView.swift diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 92298425..fe5a6c67 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -100,6 +100,8 @@ 3642999D286801C900483D0A /* typing-animation.json in Resources */ = {isa = PBXBuildFile; fileRef = DAE557FA282D00B6001F4EF1 /* typing-animation.json */; }; 364299A62868042F00483D0A /* AppCenterAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 364299A52868042F00483D0A /* AppCenterAnalytics */; }; 364299A82868042F00483D0A /* AppCenterCrashes in Frameworks */ = {isa = PBXBuildFile; productRef = 364299A72868042F00483D0A /* AppCenterCrashes */; }; + 364EF77C286F9CA000B01637 /* UserSettingsPrivacySafetyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 364EF77B286F9CA000B01637 /* UserSettingsPrivacySafetyView.swift */; }; + 364EF77D286F9CA000B01637 /* UserSettingsPrivacySafetyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 364EF77B286F9CA000B01637 /* UserSettingsPrivacySafetyView.swift */; }; 366BAA8C286D322600B662EA /* Array+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366BAA8B286D322600B662EA /* Array+.swift */; }; 366BAA8D286D322600B662EA /* Array+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366BAA8B286D322600B662EA /* Array+.swift */; }; 3684BB59283C696E005045AE /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 3684BB58283C696E005045AE /* Sparkle */; }; @@ -202,6 +204,7 @@ 36367144283C19E500A5CBE6 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; }; 364299A3286801C900483D0A /* Swiftcord.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Swiftcord.app; sourceTree = BUILT_PRODUCTS_DIR; }; 364299AD286804ED00483D0A /* Swiftcord (App Store).plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Swiftcord (App Store).plist"; sourceTree = ""; }; + 364EF77B286F9CA000B01637 /* UserSettingsPrivacySafetyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsPrivacySafetyView.swift; sourceTree = ""; }; 366BAA8B286D322600B662EA /* Array+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+.swift"; sourceTree = ""; }; 3684BB5A283C69C5005045AE /* Sparkle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sparkle.swift; sourceTree = ""; }; 36BC29F2285C162500A8B316 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; }; @@ -640,6 +643,7 @@ DA520ACE27D4CE5E009FD740 /* UserSettingsView.swift */, E7AF1C32282FB02A001F78DF /* UserSettingsAccountView.swift */, DA54D5772844DA1400B11857 /* UserSettingsProfileView.swift */, + 364EF77B286F9CA000B01637 /* UserSettingsPrivacySafetyView.swift */, ); path = User; sourceTree = ""; @@ -875,6 +879,7 @@ 36429961286801C900483D0A /* UserSettingsAccountView.swift in Sources */, 36429962286801C900483D0A /* Bool+.swift in Sources */, 36429963286801C900483D0A /* AppDelegate.swift in Sources */, + 364EF77D286F9CA000B01637 /* UserSettingsPrivacySafetyView.swift in Sources */, 36429964286801C900483D0A /* ServerButton.swift in Sources */, 36429965286801C900483D0A /* LargeUserProfileView.swift in Sources */, 36429966286801C900483D0A /* ProfileBadges.swift in Sources */, @@ -964,6 +969,7 @@ DA54D57A2844E41A00B11857 /* ProfileBadges.swift in Sources */, DAB5366B285AD15900DD9857 /* FlatButtonStyle.swift in Sources */, DA520ACF27D4CE5E009FD740 /* UserSettingsView.swift in Sources */, + 364EF77C286F9CA000B01637 /* UserSettingsPrivacySafetyView.swift in Sources */, DA67491B2833D5A9001F51CC /* AboutSwiftcordView.swift in Sources */, E7AF1C2B282FA400001F78DF /* Guild+.swift in Sources */, DA520AD527D4D120009FD740 /* ActivitySettingsView.swift in Sources */, diff --git a/Swiftcord/Commands/NavigationCommands.swift b/Swiftcord/Commands/NavigationCommands.swift index dac53338..c401e441 100644 --- a/Swiftcord/Commands/NavigationCommands.swift +++ b/Swiftcord/Commands/NavigationCommands.swift @@ -13,6 +13,7 @@ struct NavigationCommands: Commands { @ObservedObject var state: UIState @ObservedObject var gateway: DiscordGateway @State var previousServer: Snowflake? + @AppStorage("nsfwShown") var nsfwShown: Bool = true var body: some Commands { CommandMenu("Navigation") { @@ -81,14 +82,28 @@ struct NavigationCommands: Commands { } func sortChannels(_ channels: [Channel]) -> [Channel] { - let filteredChannels = channels.filter { $0.parent_id == nil && $0.type != .category && $0.type != .voice } + var filteredChannels = channels.filter { + if !nsfwShown { + return $0.parent_id == nil && $0.type != .category && $0.type != .voice && ($0.nsfw == false || $0.nsfw == nil) + } + return $0.parent_id == nil && $0.type != .category && $0.type != .voice + + }.discordSorted() + if !nsfwShown { + filteredChannels = filteredChannels.filter({ $0.nsfw == false }) + } var sortedChannels = filteredChannels let categories = channels .filter { $0.parent_id == nil && $0.type == .category } .discordSorted() for category in categories { - let categoryChannels = channels.filter({ $0.parent_id == category.id && $0.type != .voice }).discordSorted() + let categoryChannels = channels.filter({ + if !nsfwShown { + return $0.parent_id == category.id && $0.type != .category && $0.type != .voice && ($0.nsfw == false || $0.nsfw == nil) + } + return $0.parent_id == category.id && $0.type != .category && $0.type != .voice + }).discordSorted() sortedChannels.append(contentsOf: categoryChannels) } diff --git a/Swiftcord/Views/Server/ChannelList.swift b/Swiftcord/Views/Server/ChannelList.swift index a9a44e20..19d99a06 100644 --- a/Swiftcord/Views/Server/ChannelList.swift +++ b/Swiftcord/Views/Server/ChannelList.swift @@ -12,12 +12,17 @@ import DiscordKit struct ChannelList: View { let channels: [Channel] @Binding var selCh: Channel? - + @AppStorage("nsfwShown") var nsfwShown: Bool = true @EnvironmentObject var serverCtx: ServerContext var body: some View { List { - let filteredChannels = channels.filter { $0.parent_id == nil && $0.type != .category } + let filteredChannels = channels.filter { + if !nsfwShown { + return $0.parent_id == nil && $0.type != .category && ($0.nsfw == false || $0.nsfw == nil) + } + return $0.parent_id == nil && $0.type != .category + } if !filteredChannels.isEmpty { Section( header: Text(serverCtx.guild?.isDMChannel == true @@ -37,12 +42,20 @@ struct ChannelList: View { .filter { $0.parent_id == nil && $0.type == .category } .discordSorted() ForEach(categoryChannels, id: \.id) { channel in - Section(header: Text(channel.name ?? "").textCase(.uppercase)) { - // Channels in this section - let channels = channels.filter({ $0.parent_id == channel.id }).discordSorted() - ForEach(channels, id: \.id) { channel in - ChannelButton(channel: channel, selectedCh: $selCh) - .listRowInsets(.init(top: 1, leading: 0, bottom: 1, trailing: 0)) + // Channels in this section + let channels = channels.filter({ + if !nsfwShown { + return $0.parent_id == channel.id && ($0.nsfw == false || $0.nsfw == nil) + } + return $0.parent_id == channel.id + + }).discordSorted() + if !channels.isEmpty { + Section(header: Text(channel.name ?? "").textCase(.uppercase)) { + ForEach(channels, id: \.id) { channel in + ChannelButton(channel: channel, selectedCh: $selCh) + .listRowInsets(.init(top: 1, leading: 0, bottom: 1, trailing: 0)) + } } } } diff --git a/Swiftcord/Views/Settings/User/UserSettingsPrivacySafetyView.swift b/Swiftcord/Views/Settings/User/UserSettingsPrivacySafetyView.swift new file mode 100644 index 00000000..f9762ea3 --- /dev/null +++ b/Swiftcord/Views/Settings/User/UserSettingsPrivacySafetyView.swift @@ -0,0 +1,18 @@ +// +// UserSettingsPrivacySafetyView.swift +// Swiftcord +// +// Created by Andrew Glaze on 7/1/22. +// + +import SwiftUI + +struct UserSettingsPrivacySafetyView: View { + @AppStorage("nsfwShown") var nsfwShown = true + + var body: some View { + Toggle(isOn: $nsfwShown) { + Text("Show NSFW channels") + } + } +} diff --git a/Swiftcord/Views/Settings/User/UserSettingsView.swift b/Swiftcord/Views/Settings/User/UserSettingsView.swift index e4422bb2..18e26643 100644 --- a/Swiftcord/Views/Settings/User/UserSettingsView.swift +++ b/Swiftcord/Views/Settings/User/UserSettingsView.swift @@ -53,7 +53,7 @@ struct UserSettingsView: View { } NavigationLink("Privacy & Safety", tag: .privacy, selection: $selectedLink) { - Text("") + ScrollView { UserSettingsPrivacySafetyView().padding(40) } } NavigationLink("Authorized Apps", tag: .apps, selection: $selectedLink) { From 1ab5eaabc8710f36ea4b1cc88ba5104d1cba3869 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Thu, 7 Jul 2022 15:56:27 +0800 Subject: [PATCH 47/56] Better clarity of AppCenter Analytics and Crashes Now with an option to disable analytics (Preferences > App > Advanced) --- Swiftcord.xcodeproj/project.pbxproj | 19 +++++++-- Swiftcord/AppDelegate.swift | 11 +++++ Swiftcord/Utils/AnalyticsWrapper.swift | 2 + .../App/AppSettingsAdvancedView.swift | 42 +++++++++++++++++++ .../Views/Settings/App/AppSettingsView.swift | 2 +- Swiftcord/en.lproj/Localizable.strings | 8 ++++ 6 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 Swiftcord/Views/Settings/App/AppSettingsAdvancedView.swift diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index fe5a6c67..44d62426 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -170,6 +170,7 @@ DA57F44628065209001DC46E /* ChannelButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA57F44528065209001DC46E /* ChannelButton.swift */; }; DA585C9927E1F6AC00FA4EE0 /* View+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA585C9827E1F6AC00FA4EE0 /* View+.swift */; }; DA67491B2833D5A9001F51CC /* AboutSwiftcordView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA67491A2833D5A9001F51CC /* AboutSwiftcordView.swift */; }; + DA6E89F02876BC7E00BB05E7 /* AppSettingsAdvancedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6E89EF2876BC7E00BB05E7 /* AppSettingsAdvancedView.swift */; }; DA7720D0283F184100D3C335 /* NavigationCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7720CF283F184100D3C335 /* NavigationCommands.swift */; }; DA974EA22835ED1200013CC2 /* DiscordKit in Frameworks */ = {isa = PBXBuildFile; productRef = DA974EA12835ED1200013CC2 /* DiscordKit */; }; DA974EA42835ED1200013CC2 /* DiscordKitCommon in Frameworks */ = {isa = PBXBuildFile; productRef = DA974EA32835ED1200013CC2 /* DiscordKitCommon */; }; @@ -277,6 +278,7 @@ DA57F44528065209001DC46E /* ChannelButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelButton.swift; sourceTree = ""; }; DA585C9827E1F6AC00FA4EE0 /* View+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+.swift"; sourceTree = ""; }; DA67491A2833D5A9001F51CC /* AboutSwiftcordView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutSwiftcordView.swift; sourceTree = ""; }; + DA6E89EF2876BC7E00BB05E7 /* AppSettingsAdvancedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettingsAdvancedView.swift; sourceTree = ""; }; DA7720CF283F184100D3C335 /* NavigationCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCommands.swift; sourceTree = ""; }; DA97BA892848737C00059FD7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; DA97BA8B2849C0FA00059FD7 /* Cache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cache.swift; sourceTree = ""; }; @@ -662,6 +664,7 @@ DA520AD227D4D073009FD740 /* AppSettingsView.swift */, DA2BD30B284CB38B00EBB8D6 /* AppSettingsAppearanceView.swift */, DAAA22AE284DC0D700C1975E /* AppSettingsAccessibilityView.swift */, + DA6E89EF2876BC7E00BB05E7 /* AppSettingsAdvancedView.swift */, ); path = App; sourceTree = ""; @@ -943,6 +946,7 @@ DA32EF3927C77E3300A9ED72 /* AttachmentView.swift in Sources */, DAB5366E285AEDF800DD9857 /* GitHubStructs.swift in Sources */, DA2384A127CB9714009E15E0 /* Font+.swift in Sources */, + DA6E89F02876BC7E00BB05E7 /* AppSettingsAdvancedView.swift in Sources */, DAAFB5C1282A64CD00807B54 /* LoFiMessageView.swift in Sources */, DA520AC727D39A00009FD740 /* CurrentUserFooter.swift in Sources */, DA32EF4C27C8BF5000A9ED72 /* TagCloudView.swift in Sources */, @@ -1089,15 +1093,17 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Swiftcord/Swiftcord.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; - DEVELOPMENT_TEAM = RJNC97Y8QD; + DEVELOPMENT_TEAM = Q382QLKDG3; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Swiftcord/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Swiftcord; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; LD_RUNPATH_SEARCH_PATHS = ( @@ -1130,6 +1136,7 @@ ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "Swiftcord/Swiftcord (App Store).plist"; + INFOPLIST_KEY_CFBundleDisplayName = Swiftcord; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; LD_RUNPATH_SEARCH_PATHS = ( @@ -1161,6 +1168,7 @@ ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "Swiftcord/Swiftcord (App Store).plist"; + INFOPLIST_KEY_CFBundleDisplayName = Swiftcord; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; LD_RUNPATH_SEARCH_PATHS = ( @@ -1192,6 +1200,7 @@ ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "Swiftcord/Swiftcord (App Store).plist"; + INFOPLIST_KEY_CFBundleDisplayName = Swiftcord; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; LD_RUNPATH_SEARCH_PATHS = ( @@ -1336,15 +1345,17 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Swiftcord/Swiftcord.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; - DEVELOPMENT_TEAM = RJNC97Y8QD; + DEVELOPMENT_TEAM = Q382QLKDG3; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Swiftcord/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Swiftcord; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; LD_RUNPATH_SEARCH_PATHS = ( @@ -1367,15 +1378,17 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Swiftcord/Swiftcord.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; - DEVELOPMENT_TEAM = RJNC97Y8QD; + DEVELOPMENT_TEAM = Q382QLKDG3; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Swiftcord/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Swiftcord; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; INFOPLIST_KEY_NSHumanReadableCopyright = "Made with ❤️ from the Swiftcord Contributors"; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/Swiftcord/AppDelegate.swift b/Swiftcord/AppDelegate.swift index 73a56877..5ab81487 100644 --- a/Swiftcord/AppDelegate.swift +++ b/Swiftcord/AppDelegate.swift @@ -13,6 +13,7 @@ import AppCenterCrashes class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ notification: Notification) { + populateUserDefaults() setupURLCache() clearOldCache() @@ -26,6 +27,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { Analytics.self, Crashes.self ]) + Analytics.enabled = UserDefaults.standard.bool(forKey: "local.analytics") } } @@ -37,6 +39,15 @@ class AppDelegate: NSObject, NSApplicationDelegate { }*/ } +private extension AppDelegate { + func populateUserDefaults() { + UserDefaults.standard.register(defaults: [ + "local.analytics": true, + "local.seenOnboarding": false + ]) + } +} + private extension AppDelegate { /// Overwrite shared URLCache with a higher capacity one func setupURLCache() { diff --git a/Swiftcord/Utils/AnalyticsWrapper.swift b/Swiftcord/Utils/AnalyticsWrapper.swift index 045e9250..155f469d 100644 --- a/Swiftcord/Utils/AnalyticsWrapper.swift +++ b/Swiftcord/Utils/AnalyticsWrapper.swift @@ -18,6 +18,8 @@ struct AnalyticsWrapper { case guildViewed = "guild_viewed" case DMListViewed = "dm_list_viewed" case settingsPaneViewed = "settings_pane_viewed" + case analyticsEnabled = "analytics_enabled" // Seperate events for easier viewing in AppCenter + case analyticsDisabled = "analytics_disabled" } static private func getBaseProps() -> [String: Any] { diff --git a/Swiftcord/Views/Settings/App/AppSettingsAdvancedView.swift b/Swiftcord/Views/Settings/App/AppSettingsAdvancedView.swift new file mode 100644 index 00000000..0f20d552 --- /dev/null +++ b/Swiftcord/Views/Settings/App/AppSettingsAdvancedView.swift @@ -0,0 +1,42 @@ +// +// AppSettingsAdvancedView.swift +// Swiftcord +// +// Created by Vincent Kwok on 7/7/22. +// + +import SwiftUI +import AppCenterAnalytics + +struct AppSettingsAdvancedView: View { + @AppStorage("local.analytics") private var analyticsEnabled = true + @State private var hasToggledAnalytics = false + + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("settings.app.advanced").font(.title) + + Text("settings.app.advanced.analytics") + .font(.headline) + .textCase(.uppercase) + .opacity(0.75) + Toggle(isOn: $analyticsEnabled) { + Text("settings.app.advanced.analytics.option") + .frame(maxWidth: .infinity, alignment: .leading) + }.onChange(of: analyticsEnabled) { enabled in + hasToggledAnalytics = true + if enabled { + AnalyticsWrapper.event(type: .analyticsEnabled, properties: [:]) + } else { + AnalyticsWrapper.event(type: .analyticsDisabled, properties: [:]) + } + Analytics.enabled = enabled + }.disabled(hasToggledAnalytics) + Text("settings.app.advanced.analytics.caption").font(.caption) + + Divider() + + Text("settings.app.advanced.crashes") + } + } +} diff --git a/Swiftcord/Views/Settings/App/AppSettingsView.swift b/Swiftcord/Views/Settings/App/AppSettingsView.swift index 318332e5..dd0e4279 100644 --- a/Swiftcord/Views/Settings/App/AppSettingsView.swift +++ b/Swiftcord/Views/Settings/App/AppSettingsView.swift @@ -47,7 +47,7 @@ struct AppSettingsView: View { } NavigationLink("settings.app.advanced", tag: .advanced, selection: $selectedLink) { - Text("") + ScrollView { AppSettingsAdvancedView().padding(40) } } } .listStyle(SidebarListStyle()) diff --git a/Swiftcord/en.lproj/Localizable.strings b/Swiftcord/en.lproj/Localizable.strings index 80fe4bed..ca39c365 100644 --- a/Swiftcord/en.lproj/Localizable.strings +++ b/Swiftcord/en.lproj/Localizable.strings @@ -122,6 +122,14 @@ "settings.app.advanced" = "Advanced"; +"settings.app.advanced.analytics" = "Usage Matrics"; + +"settings.app.advanced.analytics.option" = "Send anonymous statistics to AppCenter Analytics to improve Swiftcord"; + +"settings.app.advanced.analytics.caption" = "Through AppCenter, aggregated (anonymous) usage statistics of Swiftcord (such as rendered language, app version and feature usages) are collected. The matrics obtained will be used to improve Swiftcord's features; we can't trace them back to you."; + +"settings.app.advanced.crashes" = "Crash traces will be sent to AppCenter after a crash to help diagnose and prevent future crashes. No logs or identifiable data will be included."; + "settings.others.debug.actions" = "Actions"; "settings.others.debug.actions.info" = "Do not use any options here unless you know what you are doing. Some of them might be DaNgErOuS!"; From 8ebffddd4555fed90db0a055a174b185b51ec915 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Thu, 7 Jul 2022 16:01:43 +0800 Subject: [PATCH 48/56] Remove settings button in channel footer on macOS > 13 --- Swiftcord/Views/User/CurrentUserFooter.swift | 27 +++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Swiftcord/Views/User/CurrentUserFooter.swift b/Swiftcord/Views/User/CurrentUserFooter.swift index 7c622c3b..1cecf842 100644 --- a/Swiftcord/Views/User/CurrentUserFooter.swift +++ b/Swiftcord/Views/User/CurrentUserFooter.swift @@ -29,15 +29,24 @@ struct CurrentUserFooter: View { Text(user.username).font(.headline) Text("#" + user.discriminator).font(.system(size: 12)).opacity(0.75) } - Spacer() - Button(action: { - NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil) - }, label: { - Image(systemName: "gearshape.fill") - .font(.system(size: 18)) - .opacity(0.75) - }).buttonStyle(.plain) - .padding(.trailing, 14) + Spacer() + + // The hidden selector for opening the preferences window + // is probably removed in macOS 13. Should check if this + // is still broken once macOS 13 is stable. + if #available(macOS 13.0, *) { + EmptyView() + } else { + Button(action: { + NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil) + }, label: { + Image(systemName: "gearshape.fill") + .font(.system(size: 18)) + .opacity(0.75) + }) + .buttonStyle(.plain) + .padding(.trailing, 14) + } } .frame(height: 52) .background(Color(NSColor.controlBackgroundColor).opacity(0.5)) From 7f83753d18e52576a1ebc8315f4f6e18cec2c008 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Thu, 7 Jul 2022 18:18:13 +0800 Subject: [PATCH 49/56] Squash Weblate translations onto main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 22cee9893429440db0551eb24968da61a5abf7b8 Author: CryptoAlgo-Dev Date: Tue Jul 5 01:38:40 2022 +0000 Translated using Weblate (Korean) Currently translated at 98.4% (62 of 63 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/ko/ commit b67b1616a10e4ca10381dd00d15c3ca676849bc3 Author: CryptoAlgo-Dev Date: Tue Jul 5 01:36:09 2022 +0000 Translated using Weblate (Norwegian Bokmål) Currently translated at 73.0% (46 of 63 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/nb_NO/ commit 190b8ff35ccef9d1eeec7c7b73daf54c7e7496ac Author: CryptoAlgo-Dev Date: Tue Jul 5 01:30:42 2022 +0000 Translated using Weblate (Italian) Currently translated at 100.0% (63 of 63 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/it/ commit e2f43e4671e4b6f35c69c865404cd6615eb74a80 Author: CryptoAlgo-Dev Date: Tue Jul 5 01:40:06 2022 +0000 Translated using Weblate (Chinese (Simplified)) Currently translated at 77.7% (49 of 63 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/zh_Hans/ commit 0aaaa2b5c3f049455b41042dfe2cc13cbb11e68e Author: CryptoAlgo-Dev Date: Tue Jul 5 01:28:31 2022 +0000 Translated using Weblate (English) Currently translated at 100.0% (63 of 63 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/en/ commit d52247e9144dc931135910715fc15422aa9a3d1d Author: alsoGAMER Date: Mon Jul 4 23:35:45 2022 +0200 Added translation using Weblate (Japanese) commit 5ad96ca6b6b8eafe120ddbc0b7490df40c7f24dd Author: jnghyk Date: Wed Jun 29 15:56:25 2022 +0000 Translated using Weblate (Korean) Currently translated at 100.0% (63 of 63 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/ko/ commit 9c365c86e6457c006b2bbd41acdcc1c49f57a605 Author: Domenico Blanco Date: Wed Jun 29 22:44:53 2022 +0000 Translated using Weblate (Italian) Currently translated at 100.0% (63 of 63 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/it/ commit 8133673596fc1146b130e2607aa996419580446f Author: Domenico Blanco Date: Thu Jun 23 18:41:41 2022 +0000 Translated using Weblate (Italian) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/it/ commit 4aa79c8e7e3248d71bc3b05a4222585fe5019a44 Author: jnghyk Date: Thu Jun 23 05:34:20 2022 +0000 Translated using Weblate (Korean) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/ko/ commit 0e0a65c995beed4c035ba9852cb5b11857ef4244 Author: InvitedToHell Date: Tue Jun 21 19:57:38 2022 +0000 Translated using Weblate (German) Currently translated at 91.3% (53 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/de/ commit f7eb1730e29a4e391b252d6d411da252a2c8511a Author: Andrew Glaze Date: Wed Jun 22 15:54:50 2022 +0000 Translated using Weblate (English) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/en/ commit a88bd506412d0e2cc4acad612be1d90f762977c1 Author: jnghyk Date: Sun Jun 19 08:47:43 2022 +0000 Translated using Weblate (Korean) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/ko/ commit 994133f5ef3ea80da3e1e49796fb1088d2ba506e Author: Allan Nordhøy Date: Sat Jun 18 09:09:52 2022 +0000 Translated using Weblate (Norwegian Bokmål) Currently translated at 82.7% (48 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/nb_NO/ commit e2d04c07d4298825661d0929af8d622f88c669cf Author: Domenico Blanco Date: Sat Jun 18 14:22:47 2022 +0000 Translated using Weblate (Italian) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/it/ commit 43504337eb5765b8c0591686f6c3a7962de5df42 Author: CryptoAlgo-Dev Date: Sat Jun 18 13:00:03 2022 +0000 Translated using Weblate (Chinese (Simplified)) Currently translated at 82.7% (48 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/zh_Hans/ commit 0eb85af72e20259ef9d9682ba0dfd3b4075838a2 Author: Allan Nordhøy Date: Sat Jun 18 13:01:02 2022 +0000 Translated using Weblate (English) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/en/ commit 3ade6dcbc80c606260843a5a236bfc7f8f12953c Author: jnghyk Date: Sat Jun 18 11:22:22 2022 +0200 Added translation using Weblate (Korean) commit c785c3aa528f00fa660da85159be400f3b087fd8 Author: Allan Nordhøy Date: Sat Jun 18 11:06:26 2022 +0200 Added translation using Weblate (Norwegian Bokmål) commit daa082552d645dc87d5b2a8df6d8a78966c51bc9 Author: J. Lavoie Date: Thu Jun 16 20:59:19 2022 +0000 Translated using Weblate (French) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/fr/ commit d4a3f535387559e0accc801d089dbb417df86cb4 Author: J. Lavoie Date: Thu Jun 16 21:09:36 2022 +0000 Translated using Weblate (German) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/de/ commit 0b285de9f27180f704814aa06949b4291921a61c Author: J. Lavoie Date: Thu Jun 16 21:00:32 2022 +0000 Translated using Weblate (Italian) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/it/ commit 61ef8e1ac2efe5dd94c4284e2e33fc6ea1e4bbaf Author: J. Lavoie Date: Thu Jun 16 22:59:05 2022 +0200 Added translation using Weblate (French) commit 27b561cd2a11c76aa89e9c7c411269fff29ca084 Author: Andrew Glaze Date: Thu Jun 16 18:52:06 2022 +0000 Translated using Weblate (English) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/en/ commit cc764751feb55d0603be58ee8a4b0c228fe33724 Author: Hosted Weblate Date: Thu Jun 16 18:24:24 2022 +0200 Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/ commit 37c15ff2897b6f381e21cb4937d2188ac0eea11b Author: Andrew Glaze Date: Thu Jun 16 18:08:57 2022 +0200 Deleted translation using Weblate (Japanese) commit 439069b777b81c45b70caf8d06543c1ec2e5b411 Author: Hosted Weblate Date: Thu Jun 16 18:04:40 2022 +0200 Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/ commit e009980f70354c0abc9f317418cc2c4942370906 Author: Domenico Blanco Date: Thu Jun 16 14:26:29 2022 +0000 Translated using Weblate (Italian) Currently translated at 100.0% (58 of 58 strings) Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/it/ commit 0cce29926cc3467920e1ced5697fb0c4f3083c4f Author: Domenico Blanco Date: Thu Jun 16 16:21:06 2022 +0200 Added translation using Weblate (Italian) commit e5629450345bffd73d0eaa518c8677e0125dbcac Author: Hosted Weblate Date: Thu Jun 16 16:19:05 2022 +0200 Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/ commit 69e8248103d81dc2348487d1c286ebc3a2b5d427 Author: Hosted Weblate Date: Thu Jun 16 16:14:03 2022 +0200 Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: Swiftcord/Swiftcord Translate-URL: https://hosted.weblate.org/projects/swiftcord/swiftcord/ commit 688199ce6889dd8e15a80a3257a3410d41232da3 Author: Andrew Glaze Date: Thu Jun 16 16:07:09 2022 +0200 Added translation using Weblate (Japanese) --- Swiftcord/de.lproj/Localizable.strings | 70 +++----------- Swiftcord/en.lproj/Localizable.strings | 72 ++------------ Swiftcord/fr.lproj/Localizable.strings | 75 +++++++++++++++ Swiftcord/it.lproj/Localizable.strings | 82 ++++++++++++++++ Swiftcord/ja.lproj/Localizable.strings | 1 + Swiftcord/ko.lproj/Localizable.strings | 82 ++++++++++++++++ Swiftcord/nb-NO.lproj/Localizable.strings | 75 +++++++++++++++ Swiftcord/zh-Hans.lproj/Localizable.strings | 100 +------------------- 8 files changed, 341 insertions(+), 216 deletions(-) create mode 100644 Swiftcord/fr.lproj/Localizable.strings create mode 100644 Swiftcord/it.lproj/Localizable.strings create mode 100644 Swiftcord/ja.lproj/Localizable.strings create mode 100644 Swiftcord/ko.lproj/Localizable.strings create mode 100644 Swiftcord/nb-NO.lproj/Localizable.strings diff --git a/Swiftcord/de.lproj/Localizable.strings b/Swiftcord/de.lproj/Localizable.strings index e66933ae..49d5a1e8 100644 --- a/Swiftcord/de.lproj/Localizable.strings +++ b/Swiftcord/de.lproj/Localizable.strings @@ -3,18 +3,13 @@ /* ====== Onboarding ====== */ "onboarding.title" = "Willkommen zu\n"; - -"onboarding.subtitle" = "Ein Discord-Client erstellt und designt nur für macOS"; - -"onboarding.lightweight.header" = "Effizient - Ressourcen schonend"; -"onboarding.lightweight.body" = "Benutzt bis zu 7x weniger RAM als Discord mit weniger CPU Beanspruchung"; - +"onboarding.subtitle" = "Ein Discord-Client erstellt und designt nur für macOS"; +"onboarding.lightweight.header" = "Effizient — Ressourcen schonend"; +"onboarding.lightweight.body" = "Benutzt bis zu 7x weniger RAM als Discord mit weniger CPU Beanspruchung."; "onboarding.features.header" = "Gut vorgestellt"; "onboarding.features.body" = "Wichtige Kern-Funktionen sind umgesetzt, weitere sind in Arbeit"; - "onboarding.wip.header" = "In Arbeit"; "onboarding.wip.body" = "Etwas ist nicht richtig? Bitte erstelle einen Fehler oder lass eine Nachricht auf unserem Discord-Server"; - "onboarding.footer" = "Swiftcord ist eine Alpha-Software, mit Begrenzungen und Fehlern. Zurzeit ist es kein Ersatzt für den offiziellen Discord-Client, aber irgendwann hoffentlich."; /* ====== Loading Cover ====== */ @@ -22,101 +17,60 @@ /* ====== User ====== */ "user.bio" = "Über mich"; - "user.roles.none" = "Keine Rollen"; - "user.roles.one" = "Rolle"; - "user.roles.many" = "Rollen"; - -"user.roles.loading" = "Lade Rollen"; - +"user.roles.loading" = "Lade Rollen…"; "user.note" = "Notiz"; /* ====== Message ====== */ "message.edited.shrunk" = " (bearbeitet)"; - "message.edited" = " • Bearbeitet: "; - "message.gone" = "Die Original-Nachricht wurde gelöscht."; - "message.reply.attachment" = "Klicke, um den Anhang zu sehen"; /* ====== Server ====== */ "server.noChannels.header" = "Keine Text Kanäle"; - "server.noChannels.body" = "Du bist an einem seltsamen Ort. Du hast entweder keinen Zugriff auf die Text-Kanäle oder es gibt diese auf diesem Server nicht."; - "server.channel.header %@ %@" = "Dies ist der Anfang von dem #%@ Kanal. %@"; - "server.channel.title %@" = "Willkommen zu #%@!"; - "server.channel.noCategory" = "Keine Kategorie"; - "server.composeMsg.hint %@" = "Nachricht #%@"; /* ====== DMs ====== */ "dm.noChannels.body" = "Wumpus wartet auf seine Freunde. Dies musst du aber nicht!"; - "dm" = "Private Nachricht"; - "dm.header %@" = "Das ist der Anfang des Privat-Nachrichten-Verlaufs **@%@**."; - "dm.group.header %@" = "Willkommen am Anfang der **%@** Gruppe."; - "dm.group.composeMsg.hint %@" = "Nachricht %@"; - "%lld dm.group.memberCount" = "%lld Mitglieder"; - "dm.composeMsg.hint %@" = "Nachricht @%@"; /* ====== Settings ====== */ -"settings.showSendBtn" = "Zeige den Nachricht senden Knopf"; - +"settings.showSendBtn" = "Nachricht senden-Knopf anzeigen"; "settings.animInteraction" = "Auf dem Desktop Client werden Sticker durch den Fokus oder das berühren der Maus animiert. An mobilen Geräten geschieht dies durch gedrückt-halten."; - -"settings.tts.rate" = "Text-zu-Sprache Geschwindigkeit"; - +"settings.tts.rate" = "Text-zu-Sprache-Geschwindigkeit"; "settings.tts.defaultSpeed" = "Standard"; - "settings.tts.slower" = "Langsamer"; - "settings.tts.faster" = "Schneller"; //////////////////////////// -"settings.user.logOut" = "Ausloggen"; - +"settings.user.logOut" = "Abmelden"; "settings.user.logOut.confirmation" = "Bist du sicher, dass du dich ausloggen möchtest?"; - "settings.app" = "App"; - "settings.app.appearance" = "Aussehen"; - -"settings.app.appearance.theme" = "Thema"; - +"settings.app.appearance.theme" = "Farbschema"; "settings.app.accessibility" = "Barrierefreiheit"; - "settings.app.accessibility.stickers" = "Sticker"; - -"settings.app.accessibility.chatInput" = "Chat Eingang"; - -"settings.app.voiceVideo" = "Ton & Video"; - -"settings.app.textImages" = "Text & Bilder"; - +"settings.app.accessibility.chatInput" = "Chat-Eingang"; +"settings.app.voiceVideo" = "Ton und Video"; +"settings.app.textImages" = "Text und Bilder"; "settings.app.notifs" = "Benachrichtigungen"; - "settings.app.keybinds" = "Tastenkürzel"; - "settings.app.lang" = "Sprache"; - -"settings.app.streamer" = "Streamer Modus"; - +"settings.app.streamer" = "Streamer-Modus"; "settings.app.advanced" = "Fortgeschritten"; - "settings.others.debug.actions" = "Aktionen"; - "settings.others.debug.actions.info" = "Verwende hier keine Optionen, wenn du nicht weißt, was passiert. Einige könnten GeFäHrLiCh sein!"; - "settings.others.debug.actions.crash" = "Lässt Swiftcord abstürzen (Kein Scherz)"; diff --git a/Swiftcord/en.lproj/Localizable.strings b/Swiftcord/en.lproj/Localizable.strings index ca39c365..9d3790e3 100644 --- a/Swiftcord/en.lproj/Localizable.strings +++ b/Swiftcord/en.lproj/Localizable.strings @@ -3,19 +3,14 @@ /* ====== Onboarding ====== */ "onboarding.title" = "Welcome to\n"; - -"onboarding.subtitle" = "A Discord client built and designed exclusively for macOS"; - -"onboarding.lightweight.header" = "Efficient - Light on Resources"; -"onboarding.lightweight.body" = "Uses up to 7x less RAM than Discord with low CPU usage"; - +"onboarding.subtitle" = "A Discord client built and designed for macOS"; +"onboarding.lightweight.header" = "Efficient — Light on Resources"; +"onboarding.lightweight.body" = "Up to 7x less RAM than Discord, with low CPU usage."; "onboarding.features.header" = "Well Featured"; -"onboarding.features.body" = "Important core features are implemented, with more in the working"; - +"onboarding.features.body" = "Important core features are implemented, with more in the works"; "onboarding.wip.header" = "Work in Progress"; -"onboarding.wip.body" = "Something's not right? Please create an issue or leave a message in the Discord server"; - -"onboarding.footer" = "Swiftcord is alpha software, with limitations and bugs. It currently isn't intended to replace the official client, but hopes to someday."; +"onboarding.wip.body" = "Something's wrong? Please create a GitHub issue or leave a message in our Discord server"; +"onboarding.footer" = "Swiftcord is alpha software, with limitations and bugs. Right now it isn't intended to replace the official client, but hopes to someday."; /* ====== Login ====== */ "login.token.title" = "Welcome to the secret token login screen!"; @@ -29,109 +24,60 @@ /* ====== User ====== */ "user.bio" = "About Me"; - "user.roles.none" = "No Roles"; - "user.roles.one" = "Role"; - "user.roles.many" = "Roles"; - -"user.roles.loading" = "Loading roles"; - +"user.roles.loading" = "Loading roles…"; "user.note" = "Note"; /* ====== Message ====== */ "message.edited.shrunk" = " (edited)"; - "message.edited" = " • Edited: "; - "message.gone" = "Original message was deleted."; - "message.reply.attachment" = "Click to see attachment"; /* ====== Server ====== */ "server.noChannels.header" = "No Text Channels"; - "server.noChannels.body" = "You find yourself in a strange place. You don't have access to any text channels or there are none in this server."; - "server.channel.header %@ %@" = "This is the start of the #%@ channel. %@"; - "server.channel.title %@" = "Welcome to #%@!"; - "server.channel.noCategory" = "No Category"; - "server.composeMsg.hint %@" = "Message #%@"; /* ====== DMs ====== */ "dm.noChannels.body" = "Wumpus is waiting on friends. You don't have to, though!"; - "dm" = "Direct Messages"; - "dm.header %@" = "This is the beginning of your direct message history with **@%@**."; - "dm.group.header %@" = "Welcome to the beginning of the **%@** group."; - "dm.group.composeMsg.hint %@" = "Message %@"; - "%lld dm.group.memberCount" = "%lld Members"; - "dm.composeMsg.hint %@" = "Message @%@"; /* ====== Settings ====== */ "settings.showSendBtn" = "Show Send Message button"; - "settings.animInteraction" = "On the desktop client, stickers will animate on hover or focus. On mobile clients, stickers will animate on long-press."; - "settings.tts.rate" = "Text-to-speech Rate"; - "settings.tts.defaultSpeed" = "Default"; - "settings.tts.slower" = "Slower"; - "settings.tts.faster" = "Faster"; //////////////////////////// "settings.user.logOut" = "Log Out"; - "settings.user.logOut.confirmation" = "Are you sure you want to log out?"; - "settings.app" = "App"; - "settings.app.appearance" = "Appearance"; - "settings.app.appearance.theme" = "Theme"; - "settings.app.accessibility" = "Accessibility"; - "settings.app.accessibility.stickers" = "Stickers"; - "settings.app.accessibility.chatInput" = "Chat Input"; - -"settings.app.voiceVideo" = "Voice & Video"; - -"settings.app.textImages" = "Text & Images"; - +"settings.app.voiceVideo" = "Voice and Video"; +"settings.app.textImages" = "Text and Images"; "settings.app.notifs" = "Notifications"; - "settings.app.keybinds" = "Keybinds"; - "settings.app.lang" = "Language"; - "settings.app.streamer" = "Streamer Mode"; - "settings.app.advanced" = "Advanced"; - -"settings.app.advanced.analytics" = "Usage Matrics"; - -"settings.app.advanced.analytics.option" = "Send anonymous statistics to AppCenter Analytics to improve Swiftcord"; - -"settings.app.advanced.analytics.caption" = "Through AppCenter, aggregated (anonymous) usage statistics of Swiftcord (such as rendered language, app version and feature usages) are collected. The matrics obtained will be used to improve Swiftcord's features; we can't trace them back to you."; - -"settings.app.advanced.crashes" = "Crash traces will be sent to AppCenter after a crash to help diagnose and prevent future crashes. No logs or identifiable data will be included."; - "settings.others.debug.actions" = "Actions"; - "settings.others.debug.actions.info" = "Do not use any options here unless you know what you are doing. Some of them might be DaNgErOuS!"; - "settings.others.debug.actions.crash" = "Crash Swiftcord (Not a joke)"; diff --git a/Swiftcord/fr.lproj/Localizable.strings b/Swiftcord/fr.lproj/Localizable.strings new file mode 100644 index 00000000..16c2a0d8 --- /dev/null +++ b/Swiftcord/fr.lproj/Localizable.strings @@ -0,0 +1,75 @@ + + +/* ====== Actions ====== */ +"action.continue" = "Continuer"; + +/* ====== Onboarding ====== */ +"onboarding.title" = "Bienvenue sur\n"; +"onboarding.subtitle" = "Un client Discord construit et conçu exclusivement pour macOS"; +"onboarding.lightweight.body" = "Utilise jusqu'à 7 fois moins de mémoire vive que Discord, avec une faible utilisation du processeur"; +"onboarding.features.header" = "Riche en fonctionnalités"; +"onboarding.features.body" = "D'importantes fonctionnalités de base sont mises en œuvre, et d'autres sont en préparation"; +"onboarding.lightweight.header" = "Efficace et économe en ressources"; +"onboarding.wip.header" = "Travail en cours"; +"onboarding.footer" = "Swiftcord est un logiciel alpha, avec des limitations et des bogues. Il n’est actuellement pas destiné à remplacer le client officiel, mais espère le faire un jour."; +"settings.user.logOut" = "Se déconnecter"; + +/* ====== User ====== */ +"user.bio" = "À propos de moi"; +"user.roles.none" = "Aucun rôle"; +"user.roles.one" = "Rôle"; +"user.roles.many" = "Rôles"; +"user.roles.loading" = "Chargement des rôles"; +"user.note" = "Note"; + +/* ====== Message ====== */ +"message.edited.shrunk" = " (modifié)"; +"message.edited" = " • Modifié : "; +"message.gone" = "Le message original a été supprimé."; + +/* ====== Server ====== */ +"server.noChannels.header" = "Aucun canal de texte"; +"server.noChannels.body" = "Vous vous trouvez dans un endroit étrange. Vous n’avez pas accès à un canal texte ou il n’y en a pas dans ce serveur."; +"server.channel.header %@ %@" = "C'est le début du canal #%@. %@"; +"server.channel.title %@" = "Bienvenue à #%@ !"; + +/* ====== DMs ====== */ +"dm.noChannels.body" = "Wumpus attend des amis. Mais pas forcément vous !"; +"dm" = "Messages directs"; +"dm.header %@" = "Ceci est le début de l'historique des messages directs avec **@%@**."; +"dm.group.header %@" = "Bienvenue au début du groupe **%@**."; +"dm.group.composeMsg.hint %@" = "Message %@"; +"%lld dm.group.memberCount" = "%lld membres"; +"dm.composeMsg.hint %@" = "Message @%@"; + +/* ====== Settings ====== */ +"settings.showSendBtn" = "Afficher le bouton Envoyer un message"; +"settings.animInteraction" = "Sur le client de bureau, les autocollants s'animeront au survol ou au focus. Sur les clients mobiles, les autocollants s'animeront en cas de pression longue."; +"settings.tts.rate" = "Vitesse de la synthèse vocale"; +"settings.tts.defaultSpeed" = "Par défaut"; +"settings.tts.slower" = "Plus lent"; +"settings.tts.faster" = "Plus rapide"; +"settings.user.logOut.confirmation" = "Êtes-vous sûr·e de vouloir vous déconnecter ?"; +"settings.app" = "Appli"; +"settings.app.appearance" = "Apparence"; +"settings.app.appearance.theme" = "Thème"; +"settings.app.accessibility.chatInput" = "Saisie de la discussion"; +"settings.app.voiceVideo" = "Voix et vidéo"; +"settings.app.textImages" = "Texte et images"; +"settings.app.notifs" = "Notifications"; +"settings.app.keybinds" = "Raccourcis clavier"; +"settings.app.streamer" = "Mode streamer"; +"settings.app.advanced" = "Avancé"; +"settings.others.debug.actions" = "Actions"; +"settings.others.debug.actions.info" = "N'utilisez pas ces options si vous ne savez pas ce que vous faites. Certaines d'entre elles peuvent être dangereuses !"; +"settings.others.debug.actions.crash" = "Planter Swiftcord (Pas une blague)"; +"onboarding.wip.body" = "Quelque chose ne va pas ? Veuillez créer un problème sur GitHub ou laisser un message sur notre serveur Discord"; + +/* ====== Loading Cover ====== */ +"loader.tip.header" = "Le saviez-vous"; +"server.channel.noCategory" = "Aucune catégorie"; +"message.reply.attachment" = "Cliquez pour voir la pièce jointe"; +"server.composeMsg.hint %@" = "Message #%@"; +"settings.app.accessibility" = "Accessibilité"; +"settings.app.lang" = "Langue"; +"settings.app.accessibility.stickers" = "Autocollants"; diff --git a/Swiftcord/it.lproj/Localizable.strings b/Swiftcord/it.lproj/Localizable.strings new file mode 100644 index 00000000..b468118e --- /dev/null +++ b/Swiftcord/it.lproj/Localizable.strings @@ -0,0 +1,82 @@ + + +"onboarding.wip.body" = "Qualcosa non va? Crea un problema su GitHub o lascia un messaggio sul nostro server Discord"; +"onboarding.features.header" = "Ricco di funzionalità"; +/* ====== Actions ====== */ +"action.continue" = "Prosegui"; + +/* ====== Onboarding ====== */ +"onboarding.title" = "Benvenuto su\n"; +"onboarding.subtitle" = "Un client Discord costruito e disegnato per macOS"; +"user.roles.one" = "Ruolo"; +"user.roles.many" = "Ruoli"; +"user.roles.loading" = "Caricamento dei ruoli…"; +"user.note" = "Nota"; + +/* ====== Message ====== */ +"message.edited.shrunk" = " (modificato)"; +"message.edited" = " • Modificato: "; +"message.gone" = "Il messaggio originale è stato eliminato."; +"message.reply.attachment" = "Clicca per vedere l'allegato"; + +/* ====== Server ====== */ +"server.noChannels.header" = "Nessun canale testuale"; +"server.noChannels.body" = "Ti ritrovi in un posto strano. Non hai accesso a nessun canale testuale o non ce ne sono in questo server."; +"server.channel.header %@ %@" = "Questo è l'inizio del canale #%@. %@"; +"server.channel.title %@" = "Benvenuto su #%@!"; +"server.channel.noCategory" = "Nessuna Categoria"; +"server.composeMsg.hint %@" = "Messaggio #%@"; +"dm" = "Messaggi diretti"; +"dm.header %@" = "Questo è l'inizio della cronologia dei tuoi messaggi con **@%@**."; +"dm.group.header %@" = "Benvenuto all'inizio del gruppo **%@**."; +"dm.group.composeMsg.hint %@" = "Messaggio %@"; +"settings.tts.defaultSpeed" = "Predefinita"; +"settings.tts.slower" = "Più lento"; +"settings.tts.faster" = "Più veloce"; +"settings.user.logOut" = "Disconnetti"; +"settings.user.logOut.confirmation" = "Sei sicuro di volerti disconnettere?"; +"settings.app" = "App"; +"settings.app.appearance" = "Aspetto"; +"settings.app.appearance.theme" = "Tema"; +"settings.app.accessibility" = "Accessibilità"; +"settings.app.accessibility.stickers" = "Stickers"; +"settings.app.lang" = "Lingua"; +"settings.app.streamer" = "Modalità Streamer"; + +/* ====== DMs ====== */ +"dm.noChannels.body" = "Wumpus sta aspettando gli amici. Tu non devi però!"; +"settings.animInteraction" = "Sul client desktop, gli sticker si animeranno posizionando il puntatore sopra di essi o premendoli. Sui client mobile, gli sticker si animeranno tenendoli premuti a lungo."; +"settings.tts.rate" = "Velocità sintesi vocale"; +"settings.app.accessibility.chatInput" = "Ingresso chat"; +"settings.app.keybinds" = "Associazioni tasti"; +"settings.others.debug.actions" = "Azioni"; +"settings.others.debug.actions.info" = "Non usare le opzioni a meno che tu non sappia cosa stai facendo. Alcune di esse possono essere PeRiCoLoSe!"; +"settings.others.debug.actions.crash" = "Fai crashare Swiftcord (Sul serio)"; +"onboarding.lightweight.header" = "Efficiente — Consumo ridotto di Risorse"; +"onboarding.lightweight.body" = "Fino a 7 volte in meno la RAM rispetto a Discord, con un basso consumo di CPU."; +"onboarding.wip.header" = "In lavorazione"; +"onboarding.features.body" = "Importanti funzionalità di base, altre sono in fase di realizzazione"; +"onboarding.footer" = "Swiftcord è un software in alpha, con limiti e bug. Attualmente non è pensato a rimpiazzare il client ufficiale, ma spera di poterlo fare un giorno."; + +/* ====== Settings ====== */ +"settings.showSendBtn" = "Mostra il bottone Manda messaggio"; + +/* ====== Loading Cover ====== */ +"loader.tip.header" = "Sai"; + +/* ====== User ====== */ +"user.bio" = "Su di me"; +"user.roles.none" = "Nessun ruolo"; +"settings.app.voiceVideo" = "Voce e video"; +"settings.app.notifs" = "Notifiche"; +"%lld dm.group.memberCount" = "%lld Membri"; +"settings.app.textImages" = "Testo e immagini"; +"dm.composeMsg.hint %@" = "Messaggio @%@"; +"settings.app.advanced" = "Avanzate"; +"login.token.back" = "Aspetta, torna indietro"; +"login.token.login" = "Accesso"; +"loader.panic.logout" = "Ci sta mettendo un po', vuoi disconnetterti?"; + +/* ====== Login ====== */ +"login.token.title" = "Benvenuto nella schermata segreta di accesso con token!"; +"login.token.input" = "Incolla qui il tuo token di Discord"; diff --git a/Swiftcord/ja.lproj/Localizable.strings b/Swiftcord/ja.lproj/Localizable.strings new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Swiftcord/ja.lproj/Localizable.strings @@ -0,0 +1 @@ + diff --git a/Swiftcord/ko.lproj/Localizable.strings b/Swiftcord/ko.lproj/Localizable.strings new file mode 100644 index 00000000..adb6a3c2 --- /dev/null +++ b/Swiftcord/ko.lproj/Localizable.strings @@ -0,0 +1,82 @@ + + +"onboarding.footer" = "Swiftcord는 버그나 제한 사항이 있는 알파 버전입니다. 현재 공식 클라이언트를 완전히 대체하지 않습니다."; +/* ====== Actions ====== */ +"action.continue" = "계속"; +"onboarding.lightweight.header" = "전력 효율성 - 가벼움"; +"onboarding.features.header" = "풍부한 기능"; + +/* ====== Loading Cover ====== */ +"loader.tip.header" = "알고 계셨나요?"; + +/* ====== User ====== */ +"user.bio" = "내 소개"; +"user.roles.none" = "역할 없음"; +"user.roles.one" = "역할"; +"user.roles.many" = "역할"; +"user.note" = "메모"; + +/* ====== Message ====== */ +"message.edited.shrunk" = " (수정됨)"; +"message.edited" = " • 수정됨: "; +"message.gone" = "원본 메시지가 삭제되었어요."; +"message.reply.attachment" = "첨부 파일을 보려면 클릭하세요"; +"server.noChannels.body" = "난처한 상황에 처하셨군요. 채팅 채널 사용 권한이 없거나 서버에 채팅 채널이 없네요."; +"server.channel.noCategory" = "카테고리 없음"; +"server.composeMsg.hint %@" = "#%@ 에 메시지 보내기"; +"onboarding.wip.header" = "개발 진행중"; +"onboarding.subtitle" = "macOS용으로 제작 및 설계된 Discord 클라이언트"; +"onboarding.wip.body" = "뭔가 잘못되었나요? Github에 이슈를 생성하거나 Discord 서버에 메시지를 남겨주세요."; +"onboarding.lightweight.body" = "Discord 대비 최대 7배 적은 메모리 사용 및 낮은 CPU 부담."; +"user.roles.loading" = "역할 로딩중…"; +"settings.app.accessibility.stickers" = "스티커"; + +/* ====== DMs ====== */ +"dm.noChannels.body" = "Wumpus는 친구를 기다리고 있어요!"; +"settings.app.appearance" = "디스플레이"; +"settings.app.accessibility" = "접근성"; +"settings.app.voiceVideo" = "음성 및 비디오"; +"settings.app.textImages" = "텍스트 및 사진"; +"settings.app.notifs" = "알림"; +"settings.app.keybinds" = "단축키"; +"settings.app.lang" = "언어"; +"settings.app.streamer" = "스트리머 모드"; +"settings.app.advanced" = "고급"; +"settings.tts.rate" = "텍스트 음성 변환 속도"; +"settings.tts.defaultSpeed" = "기본"; +"settings.tts.slower" = "느리게"; +"settings.tts.faster" = "빠르게"; +"settings.user.logOut" = "로그아웃"; +"settings.user.logOut.confirmation" = "로그아웃 하시겠습니까?"; +"settings.app" = "앱"; + +/* ====== Settings ====== */ +"settings.showSendBtn" = "메시지 보내기 버튼 보기"; +"settings.app.appearance.theme" = "테마"; +"settings.others.debug.actions" = "Actions"; +"settings.others.debug.actions.info" = "Do not use any options here unless you know what you are doing. Some of them might be DaNgErOuS!"; +"dm.header %@" = "**@%@** 님과 나눈 대화의 첫 부분이에요."; +"dm.group.header %@" = "**%@** 그룹에 들어온 걸 환영해요."; +"dm.group.composeMsg.hint %@" = "%@ 에 메시지 보내기"; +"%lld dm.group.memberCount" = "멤버 %lld명"; +"dm.composeMsg.hint %@" = "@%@ 에 메시지 보내기"; +"settings.app.accessibility.chatInput" = "채팅 입력"; +"dm" = "다이렉트 메시지"; +"settings.animInteraction" = "스티커는 마우스를 올리거나 활성화된 창에서 움직입니다. 모바일에서는 길게 누르면 움직입니다."; +"settings.others.debug.actions.crash" = "Crash Swiftcord (Not a joke)"; +"onboarding.features.body" = "핵심 기능이 구현되었으며 더 많은 기능이 제공될 예정입니다"; + +/* ====== Server ====== */ +"server.noChannels.header" = "채팅 채널 없음"; + +/* ====== Onboarding ====== */ +"onboarding.title" = "환영합니다\n"; +"server.channel.title %@" = "#%@ 에 오신 걸 환영합니다!"; +"server.channel.header %@ %@" = "#%@ 채널의 시작이에요. %@"; +"loader.panic.logout" = "시간이 좀 걸리는군요, 로그아웃하시겠습니까?"; +"login.token.back" = "뒤로가기"; +"login.token.input" = "Discord 토큰 붙여넣기"; + +/* ====== Login ====== */ +"login.token.title" = "비밀 토큰 로그인 화면에 오신 것을 환영합니다!"; +"login.token.login" = "로그인"; diff --git a/Swiftcord/nb-NO.lproj/Localizable.strings b/Swiftcord/nb-NO.lproj/Localizable.strings new file mode 100644 index 00000000..8ee4b005 --- /dev/null +++ b/Swiftcord/nb-NO.lproj/Localizable.strings @@ -0,0 +1,75 @@ + + +"onboarding.features.header" = "Rikholdig funksjonalitet"; +"onboarding.wip.header" = "Underveis"; + +/* ====== Loading Cover ====== */ +"loader.tip.header" = "Visste du?"; + +/* ====== User ====== */ +"user.bio" = "Om meg"; +"user.roles.none" = "Ingen roller"; +"user.roles.one" = "Rolle"; +"user.roles.many" = "Roller"; + +/* ====== Message ====== */ +"message.edited.shrunk" = " (redigert)"; +"message.edited" = " • Redigert: "; +"message.gone" = "Den opprinnelige meldingen ble slettet."; +"message.reply.attachment" = "Klikk for å se vedlegget"; + +/* ====== Server ====== */ +"server.noChannels.header" = "Ingen tekstkanaler"; +"server.channel.title %@" = "Velkommen til #%@!"; +"server.channel.noCategory" = "Uten kategori"; +"server.composeMsg.hint %@" = "Melding #%@"; +"dm" = "Direktemeldinger"; +"dm.group.header %@" = "Velkommen til begynnelsen av **%@**-gruppen."; +"%lld dm.group.memberCount" = "%lld medlemmer"; +"dm.composeMsg.hint %@" = "Melding @%@"; + +/* ====== Settings ====== */ +"settings.showSendBtn" = "Vis knapp for meldingsforsendelse"; +"settings.tts.rate" = "Tekst-til-tale -takt"; +"settings.tts.defaultSpeed" = "Forvalg"; +"settings.tts.slower" = "Tregere"; +"settings.tts.faster" = "Raskere"; +"settings.user.logOut" = "Logg ut"; +"settings.app" = "Program"; +"settings.app.appearance" = "Utseende"; +"settings.app.appearance.theme" = "Drakt"; +"settings.app.accessibility" = "Tilgjengelighet"; +"user.note" = "Notis"; +"server.channel.header %@ %@" = "Dette er starten på #%@-kanalen. %@"; + +/* ====== DMs ====== */ +"dm.noChannels.body" = "Wumpus venter åp venner. Det trenger ikke du å gjøre dog!"; +"user.roles.loading" = "Laster inn roller …"; +"onboarding.lightweight.header" = "Formålstjenlig — lav ressursbruk."; +"onboarding.lightweight.body" = "Opptil 7x mindre minne i sving enn Discord, og lav prosessorbruk."; +"onboarding.features.body" = "Viktige kjernefunksjoner, med flere underveis."; +"onboarding.subtitle" = "En Discord-klient bygd og designet for macOS"; +"settings.app.accessibility.stickers" = "Klistremerker"; +"settings.app.accessibility.chatInput" = "Sludreinndata"; +"settings.app.notifs" = "Merknader"; +"settings.app.lang" = "Språk"; +"settings.app.advanced" = "Avansert"; +"settings.others.debug.actions" = "Handlinger"; +"settings.others.debug.actions.crash" = "Krasj Swiftcord (ikke en vits)"; +"settings.app.keybinds" = "Hurtigtaster"; +"settings.app.streamer" = "Modus for delere"; +"settings.others.debug.actions.info" = "Ikke bruk noe her med mindre du vet hva du gjør. Noen av valgene kan være fArLiGe!"; +"settings.app.voiceVideo" = "Stemme og lyd"; +"settings.app.textImages" = "Tekst og bilder"; +/* ====== Actions ====== */ +"action.continue" = "Fortsett"; + +/* ====== Onboarding ====== */ +"onboarding.title" = "Velkommen til\n"; +"onboarding.wip.body" = "Er noe galt? Opprett en feilrapport på GitHub, eller levn en melding i vår Discord-tjener"; +"onboarding.footer" = "Alfa-programvare, med begrensninger og feil. Tar foreløpig kun sikte å erstatte den offisielle klienten."; +"dm.group.composeMsg.hint %@" = "Melding %@"; +"settings.user.logOut.confirmation" = "Logg ut?"; +"dm.header %@" = "Dette er begynnelsen på din sludringshistorikk med **@%@**."; +"server.noChannels.body" = "Du befinner deg på et merkelig sted, uten tilgang til tekstkanaler. Enten det, eller så finnes det ikke noen på denne tjeneren."; +"settings.animInteraction" = "For skrivebordsklienten vil klistremerker animeres når du holder pekeren over dem. På mobilklienten skjer dette ved lang-trykk."; diff --git a/Swiftcord/zh-Hans.lproj/Localizable.strings b/Swiftcord/zh-Hans.lproj/Localizable.strings index 3245ed03..9d94990e 100644 --- a/Swiftcord/zh-Hans.lproj/Localizable.strings +++ b/Swiftcord/zh-Hans.lproj/Localizable.strings @@ -3,18 +3,13 @@ /* ====== Onboarding ====== */ "onboarding.title" = "欢迎使用\n"; - "onboarding.subtitle" = "专为macOS打造和设计的Discord客户端"; - -"onboarding.lightweight.header" = "Efficient - Light on Resources"; -"onboarding.lightweight.body" = "Uses up to 7x less RAM than Discord with low CPU usage"; - -"onboarding.features.header" = "Well Featured"; -"onboarding.features.body" = "Important core features are implemented, with more in the working"; - +"onboarding.lightweight.header" = "高效—轻量级的资源"; +"onboarding.lightweight.body" = "使用的内存比Discord少7倍,CPU使用率低。"; +"onboarding.features.header" = "功能完善"; +"onboarding.features.body" = "核心功能已经实现,更多的功能正在进行中"; "onboarding.wip.header" = "Work in Progress"; "onboarding.wip.body" = "Something's not right? Please create an issue or leave a message in the Discord server"; - "onboarding.footer" = "Swiftcord是初期的软件,有限制和错误。它目前并不打算取代官方客户端,但希望有朝一日能够取代。"; /* ====== Loading Cover ====== */ @@ -23,142 +18,57 @@ /* ====== User ====== */ "user.roles.one" = "身份组"; - -/* No comment provided by engineer. */ "user.roles.many" = "身份组"; - -/* No comment provided by engineer. */ "user.roles.none" = "没有身份组"; - "user.roles.loading" = "加载身份组"; - "user.bio" = "自我介绍"; - "user.note" = "备注"; /* ====== Message ====== */ "message.edited.shrunk" = " (已编辑)"; - "message.edited" = " • 已编辑: "; - "message.gone" = "原始消息已被删除。"; - "message.reply.attachment" = "点击查看附件"; -/* No comment provided by engineer. */ -"Connections" = "连接​​​​​​​​"; - -/* No comment provided by engineer. */ -"Copy ID" = "复制 ID"; - -/* No comment provided by engineer. */ -"Copy Link" = "复制链接"; - -/* No comment provided by engineer. */ -"Create Thread" = "创建子区"; - -/* No comment provided by engineer. */ -"Discord Nitro" = "Nitro"; - -/* No comment provided by engineer. */ -"Done" = "编辑信息"; - -/* No comment provided by engineer. */ -"My Account" = "我的账号"; - -/* No comment provided by engineer. */ -"Navigation" = "导航"; - -/* No comment provided by engineer. */ -"Next Channel" = "下个起点"; - -/* No comment provided by engineer. */ -"Previous Channel" = "前个起点"; - -/* No comment provided by engineer. */ -"Privacy & Safety" = "隐私与安全"; - -/* No comment provided by engineer. */ -"Remove attachment" = "移除附件"; - -/* No comment provided by engineer. */ -"Reply" = "回复"; - -/* No comment provided by engineer. */ -"Server Boost" = "服务器助力"; - -/* No comment provided by engineer. */ -"User Profile" = "用户个人资料"; - /* ====== Server ====== */ "server.noChannels.header" = "无文字频道"; - "server.noChannels.body" = "您发现您身处一个奇怪的地方。您没有权限访问任何文字频道,或者此服务器上没有文字频道。"; - "server.channel.header %@ %@" = "这是 #%@ 频道的起点。%@"; - "server.channel.title %@" = "欢迎来到 #%@!"; - "server.channel.noCategory" = "没类别"; - "server.composeMsg.hint %@" = "给 #%@ 发消息"; /* ====== DMs ====== */ "dm.noChannels.body" = "Wumpus在苦等自己的朋友。不过您不用等哦!"; - "dm" = "私信"; - "dm.header %@" = "这是您与 **@%@** 私信记录的开头。"; - "dm.group.header %@" = "欢迎来到 **%@** 组的开头。"; - "dm.group.composeMsg.hint %@" = "给 %@ 发消息"; - "%lld dm.group.memberCount" = "成员"; - "dm.composeMsg.hint %@" = "消息@%@"; /* ====== Settings ====== */ "settings.showSendBtn" = "显示发送消息按钮"; - "settings.animInteraction" = "在桌面客户端上,贴纸会在鼠标悬停或聚焦时进入动画状态。在移动客户端上,贴纸会在长按时进入动画状态。"; - "settings.tts.rate" = "文字转语音速度"; - "settings.tts.defaultSpeed" = "默认"; - "settings.tts.slower" = "更慢"; - "settings.tts.faster" = "更快"; //////////////////////////// "settings.user.logOut" = "登出"; - -"settings.user.logOut.confirmation" = "您确定您要退出登录吗?"; - +"settings.user.logOut.confirmation" = "确定登出?"; "settings.app" = "应用"; - "settings.app.appearance" = "外观"; - "settings.app.appearance.theme" = "主题"; - "settings.app.accessibility" = "可访问性"; - "settings.app.accessibility.stickers" = "贴纸"; - "settings.app.accessibility.chatInput" = "输入消息"; - "settings.app.voiceVideo" = "语音和视频"; - "settings.app.textImages" = "文字与图像"; - "settings.app.notifs" = "通知"; - "settings.app.keybinds" = "快捷键"; - "settings.app.lang" = "语言"; - "settings.app.streamer" = "主播模式"; - "settings.app.advanced" = "高级设置"; From 55eec23618db93f2ea935b136ef7fdb17c1e6bfb Mon Sep 17 00:00:00 2001 From: vinkwok Date: Thu, 7 Jul 2022 18:21:47 +0800 Subject: [PATCH 50/56] Add English strings for advanced settings --- Swiftcord/en.lproj/Localizable.strings | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Swiftcord/en.lproj/Localizable.strings b/Swiftcord/en.lproj/Localizable.strings index 9d3790e3..90c2d90c 100644 --- a/Swiftcord/en.lproj/Localizable.strings +++ b/Swiftcord/en.lproj/Localizable.strings @@ -78,6 +78,10 @@ "settings.app.lang" = "Language"; "settings.app.streamer" = "Streamer Mode"; "settings.app.advanced" = "Advanced"; +"settings.app.advanced.analytics" = "Usage Matrics"; +"settings.app.advanced.analytics.option" = "Send anonymous statistics to AppCenter Analytics to improve Swiftcord"; +"settings.app.advanced.analytics.caption" = "Through AppCenter, aggregated (anonymous) usage statistics of Swiftcord (such as rendered language, app version and feature usages) are collected. The matrics obtained will be used to improve Swiftcord's features; we can't trace them back to you."; +"settings.app.advanced.crashes" = "Crash traces will be sent to AppCenter after a crash to help diagnose and prevent future crashes. No logs or identifiable data will be included."; "settings.others.debug.actions" = "Actions"; "settings.others.debug.actions.info" = "Do not use any options here unless you know what you are doing. Some of them might be DaNgErOuS!"; "settings.others.debug.actions.crash" = "Crash Swiftcord (Not a joke)"; From 8a6dce0e0c21ea0769a3c0e92a0ec2de04c6195e Mon Sep 17 00:00:00 2001 From: CryptoAlgo-Dev Date: Thu, 7 Jul 2022 13:05:34 +0200 Subject: [PATCH 51/56] Deleted translation using Weblate (Japanese) --- Swiftcord/ja.lproj/Localizable.strings | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Swiftcord/ja.lproj/Localizable.strings diff --git a/Swiftcord/ja.lproj/Localizable.strings b/Swiftcord/ja.lproj/Localizable.strings deleted file mode 100644 index 8b137891..00000000 --- a/Swiftcord/ja.lproj/Localizable.strings +++ /dev/null @@ -1 +0,0 @@ - From d8d4f22f15ad93dc65433a09ef23aae4633c5b0b Mon Sep 17 00:00:00 2001 From: vinkwok Date: Thu, 7 Jul 2022 19:21:15 +0800 Subject: [PATCH 52/56] v0.4.2 pre-release updates Added missing file to app store target --- Swiftcord.xcodeproj/project.pbxproj | 30 +- .../en.xcloc/Localized Contents/en.xliff | 804 ------------------ .../Swiftcord/en.lproj/InfoPlist.strings | 4 - .../Swiftcord/en.lproj/Localizable.strings | 468 ---------- .../en.xcloc/contents.json | 12 - .../Localized Contents/zh-Hans.xliff | 674 --------------- .../Swiftcord/en.lproj/InfoPlist.strings | 4 - .../Swiftcord/en.lproj/Localizable.strings | 468 ---------- .../zh-Hans.xcloc/contents.json | 12 - 9 files changed, 16 insertions(+), 2460 deletions(-) delete mode 100644 Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Localized Contents/en.xliff delete mode 100644 Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Source Contents/Swiftcord/en.lproj/InfoPlist.strings delete mode 100644 Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Source Contents/Swiftcord/en.lproj/Localizable.strings delete mode 100644 Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/contents.json delete mode 100644 Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff delete mode 100644 Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Source Contents/Swiftcord/en.lproj/InfoPlist.strings delete mode 100644 Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Source Contents/Swiftcord/en.lproj/Localizable.strings delete mode 100644 Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/contents.json diff --git a/Swiftcord.xcodeproj/project.pbxproj b/Swiftcord.xcodeproj/project.pbxproj index 44d62426..bd1193a4 100644 --- a/Swiftcord.xcodeproj/project.pbxproj +++ b/Swiftcord.xcodeproj/project.pbxproj @@ -138,6 +138,7 @@ DA32EF5227C8FBB200A9ED72 /* User+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF5127C8FBB200A9ED72 /* User+.swift */; }; DA32EF5927CB5F4F00A9ED72 /* UIStateEnv.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF5827CB5F4F00A9ED72 /* UIStateEnv.swift */; }; DA32EF6627CB772300A9ED72 /* CacheModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA32EF6427CB772300A9ED72 /* CacheModel.xcdatamodeld */; }; + DA4350002876F67F001DEC81 /* AppSettingsAdvancedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6E89EF2876BC7E00BB05E7 /* AppSettingsAdvancedView.swift */; }; DA4A888827C0AF3000720909 /* SwiftcordApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4A888727C0AF3000720909 /* SwiftcordApp.swift */; }; DA4A888A27C0AF3000720909 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4A888927C0AF3000720909 /* ContentView.swift */; }; DA4A888C27C0AF3200720909 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA4A888B27C0AF3200720909 /* Assets.xcassets */; }; @@ -902,6 +903,7 @@ 36429974286801C900483D0A /* Message+.swift in Sources */, 36429975286801C900483D0A /* MediaControllerView.swift in Sources */, 36429976286801C900483D0A /* Double+.swift in Sources */, + DA4350002876F67F001DEC81 /* AppSettingsAdvancedView.swift in Sources */, 36429977286801C900483D0A /* MessagesView+.swift in Sources */, 36429978286801C900483D0A /* SettingsView.swift in Sources */, 36429979286801C900483D0A /* UserAvatarView.swift in Sources */, @@ -1096,7 +1098,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; DEVELOPMENT_TEAM = Q382QLKDG3; ENABLE_HARDENED_RUNTIME = YES; @@ -1111,7 +1113,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 0.4.1; + MARKETING_VERSION = 0.4.2; PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = APP_STORE; @@ -1129,7 +1131,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; DEVELOPMENT_TEAM = RJNC97Y8QD; ENABLE_HARDENED_RUNTIME = YES; @@ -1144,7 +1146,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 0.4.1; + MARKETING_VERSION = 0.4.2; PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; PRODUCT_NAME = Swiftcord; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1161,7 +1163,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; DEVELOPMENT_TEAM = RJNC97Y8QD; ENABLE_HARDENED_RUNTIME = YES; @@ -1176,7 +1178,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 0.4.1; + MARKETING_VERSION = 0.4.2; PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; PRODUCT_NAME = Swiftcord; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1193,7 +1195,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; DEVELOPMENT_TEAM = RJNC97Y8QD; ENABLE_HARDENED_RUNTIME = YES; @@ -1208,7 +1210,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 0.4.1; + MARKETING_VERSION = 0.4.2; PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; PRODUCT_NAME = Swiftcord; SWIFT_ACTIVE_COMPILATION_CONDITIONS = APP_STORE; @@ -1348,7 +1350,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; DEVELOPMENT_TEAM = Q382QLKDG3; ENABLE_HARDENED_RUNTIME = YES; @@ -1363,7 +1365,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 0.4.1; + MARKETING_VERSION = 0.4.2; PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1381,7 +1383,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_ASSET_PATHS = "\"Swiftcord/Preview Content\""; DEVELOPMENT_TEAM = Q382QLKDG3; ENABLE_HARDENED_RUNTIME = YES; @@ -1396,7 +1398,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 0.4.1; + MARKETING_VERSION = 0.4.2; PRODUCT_BUNDLE_IDENTIFIER = io.cryptoalgo.swiftcord; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1492,8 +1494,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/SwiftcordApp/DiscordKit"; requirement = { - branch = main; - kind = branch; + kind = revision; + revision = 5cc5888a2bd66b7c1575d7c926b12f31d3659fcd; }; }; DA97BA8E2849F9C500059FD7 /* XCRemoteSwiftPackageReference "appcenter-sdk-apple" */ = { diff --git a/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Localized Contents/en.xliff b/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Localized Contents/en.xliff deleted file mode 100644 index 3d33fb24..00000000 --- a/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Localized Contents/en.xliff +++ /dev/null @@ -1,804 +0,0 @@ - - - -
- -
- - - Swiftcord - Swiftcord - Bundle name - - - Copyright © 2022 Vincent Kwok. -All rights reserved. - Copyright © 2022 Vincent Kwok. -All rights reserved. - Copyright (human-readable) - - -
- -
- -
- - - %@ typing... - %@ typing... - No comment provided by engineer. - - - (edited) - (edited) - No comment provided by engineer. - - - group. - group. - No comment provided by engineer. - - - #%@ - #%@ - No comment provided by engineer. - - - $$$ 💸 - $$$ 💸 - No comment provided by engineer. - - - %@ - %@ - No comment provided by engineer. - - - %@ • %@ - %@ • %@ - No comment provided by engineer. - - - %lld Members - %lld Members - No comment provided by engineer. - - - . - . - No comment provided by engineer. - - - @%@ - @%@ - No comment provided by engineer. - - - A completely native Discord client for macOS built 100% in Swift and SwiftUI. Light on your CPU and RAM. - A completely native Discord client for macOS built 100% in Swift and SwiftUI. Light on your CPU and RAM. - No comment provided by engineer. - - - ABOUT ME - ABOUT ME - No comment provided by engineer. - - - ACCOUNT REMOVAL - ACCOUNT REMOVAL - No comment provided by engineer. - - - About - About - No comment provided by engineer. - - - Accessibility - Accessibility - No comment provided by engineer. - - - Activity - Activity - No comment provided by engineer. - - - Activity Status - Activity Status - No comment provided by engineer. - - - Add Reaction - Add Reaction - No comment provided by engineer. - - - Add a note to this user (only visible to you) - Add a note to this user (only visible to you) - No comment provided by engineer. - - - Advanced - Advanced - No comment provided by engineer. - - - And finally, thanks to Discord for building such an amazing community and infrastructure! - And finally, thanks to Discord for building such an amazing community and infrastructure! - No comment provided by engineer. - - - Anthony Ingle - Anthony Ingle - No comment provided by engineer. - - - App - App - No comment provided by engineer. - - - Appearance - Appearance - No comment provided by engineer. - - - Append to queue - Append to queue - No comment provided by engineer. - - - Are you sure you want to log out? - Are you sure you want to log out? - No comment provided by engineer. - - - Authorized Apps - Authorized Apps - No comment provided by engineer. - - - BOT - BOT - No comment provided by engineer. - - - Ben Tettmar - Ben Tettmar - No comment provided by engineer. - - - Big thanks to all contributors <3! Contributions are more than welcome :D - Big thanks to all contributors <3! Contributions are more than welcome :D - No comment provided by engineer. - - - Billing - Billing - No comment provided by engineer. - - - Candygoblen123 - Candygoblen123 - No comment provided by engineer. - - - Change Log - Change Log - No comment provided by engineer. - - - Change Password - Change Password - No comment provided by engineer. - - - Change your password - Change your password - No comment provided by engineer. - - - Check for Updates… - Check for Updates… - No comment provided by engineer. - - - Click to see attachment - Click to see attachment - No comment provided by engineer. - - - Close - Close - No comment provided by engineer. - - - Connections - Connections - No comment provided by engineer. - - - Contributors - Contributors - No comment provided by engineer. - - - Copy ID - Copy ID - No comment provided by engineer. - - - Copy Link - Copy Link - No comment provided by engineer. - - - Create Thread - Create Thread - No comment provided by engineer. - - - Create/Join Server - Create/Join Server - No comment provided by engineer. - - - Credits - Credits - No comment provided by engineer. - - - Cue Discord ping sound - Cue Discord ping sound - No comment provided by engineer. - - - DMs - DMs - No comment provided by engineer. - - - Debug - Debug - No comment provided by engineer. - - - Delete Account - Delete Account - No comment provided by engineer. - - - Delete Message - Delete Message - No comment provided by engineer. - - - Disable Account - Disable Account - No comment provided by engineer. - - - Disabling your account means you can recover it at any time after taking this action. - Disabling your account means you can recover it at any time after taking this action. - No comment provided by engineer. - - - Discord Nitro - Discord Nitro - No comment provided by engineer. - - - Don't get nitro, nitro bad - Don't get nitro, nitro bad - No comment provided by engineer. - - - Done - Done - No comment provided by engineer. - - - Download attachment - Download attachment - No comment provided by engineer. - - - Drop file to add attachment - Drop file to add attachment - No comment provided by engineer. - - - EMAIL - EMAIL - No comment provided by engineer. - - - Edit - Edit - No comment provided by engineer. - - - Enter your current password and a new one. - Enter your current password and a new one. - No comment provided by engineer. - - - Failed to get full user profile - Failed to get full user profile - No comment provided by engineer. - - - Gateway isn't connected - Gateway isn't connected - No comment provided by engineer. - - - Gift Inventory - Gift Inventory - No comment provided by engineer. - - - Got It! - Got It! - No comment provided by engineer. - - - Head Developer - Head Developer - No comment provided by engineer. - - - Hello, World! - Hello, World! - No comment provided by engineer. - - - Hypesquad - Hypesquad - No comment provided by engineer. - - - Item - Item - No comment provided by engineer. - - - Keybinds - Keybinds - No comment provided by engineer. - - - LOADING ROLES - LOADING ROLES - No comment provided by engineer. - - - Language - Language - No comment provided by engineer. - - - Loading Discord login... - Loading Discord login... - No comment provided by engineer. - - - Loading full profile... - Loading full profile... - No comment provided by engineer. - - - Loading roles... - Loading roles... - No comment provided by engineer. - - - Loading sticker... - Loading sticker... - No comment provided by engineer. - - - Log Out - Log Out - No comment provided by engineer. - - - Manage Server Webhooks - Manage Server Webhooks - No comment provided by engineer. - - - Media Center - Media Center - No comment provided by engineer. - - - My Account - My Account - No comment provided by engineer. - - - NO ROLES - NO ROLES - No comment provided by engineer. - - - NO TEXT CHANNELS - NO TEXT CHANNELS - No comment provided by engineer. - - - NOTE - NOTE - No comment provided by engineer. - - - Navigation - Navigation - No comment provided by engineer. - - - Next Channel - Next Channel - No comment provided by engineer. - - - Next Server - Next Server - No comment provided by engineer. - - - No network connectivity - No network connectivity - No comment provided by engineer. - - - No server selected - No server selected - No comment provided by engineer. - - - Not hype - Not hype - No comment provided by engineer. - - - Nothing - Nothing - No comment provided by engineer. - - - Nothing in queue - Nothing in queue - No comment provided by engineer. - - - Notifications - Notifications - No comment provided by engineer. - - - Original message was deleted. - Original message was deleted. - No comment provided by engineer. - - - Others - Others - No comment provided by engineer. - - - PHONE NUMBER - PHONE NUMBER - No comment provided by engineer. - - - PREVIEW - PREVIEW - No comment provided by engineer. - - - Password and Authenthication - Password and Authenthication - No comment provided by engineer. - - - Pin Message - Pin Message - No comment provided by engineer. - - - Play now - Play now - No comment provided by engineer. - - - - Preview attachment - Preview attachment - No comment provided by engineer. - - - Previous Channel - Previous Channel - No comment provided by engineer. - - - Previous Server - Previous Server - No comment provided by engineer. - - - Privacy & Safety - Privacy & Safety - No comment provided by engineer. - - - Quit - Quit - No comment provided by engineer. - - - ROLE - ROLE - No comment provided by engineer. - - - ROLES - ROLES - No comment provided by engineer. - - - Reconnecting... - Reconnecting... - No comment provided by engineer. - - - Remove 2FA - Remove 2FA - No comment provided by engineer. - - - Remove attachment - Remove attachment - No comment provided by engineer. - - - Reply - Reply - No comment provided by engineer. - - - Server Boost - Server Boost - No comment provided by engineer. - - - Settings can only be modified after logging in and while the gateway is connected. - Settings can only be modified after logging in and while the gateway is connected. - No comment provided by engineer. - - - Sorry, aPNG stickers can't be played (yet) - Sorry, aPNG stickers can't be played (yet) - No comment provided by engineer. - - - Sponsoring Swiftcord allows me to continue developing it! - Sponsoring Swiftcord allows me to continue developing it! - No comment provided by engineer. - - - Sponsors - Sponsors - No comment provided by engineer. - - - Sticker Pack - Sticker Pack - No comment provided by engineer. - - - Streamer Mode - Streamer Mode - No comment provided by engineer. - - - Subscriptions - Subscriptions - No comment provided by engineer. - - - Swiftcord - Swiftcord - No comment provided by engineer. - - - Swiftcord is open-source software and built with love. You can find its source code in GitHub at the link below! Contributions and issue reports are welcome ;) Please also give Swiftcord a star, it gives me motivation to continue working on it. - Swiftcord is open-source software and built with love. You can find its source code in GitHub at the link below! Contributions and issue reports are welcome ;) Please also give Swiftcord a star, it gives me motivation to continue working on it. - No comment provided by engineer. - - - Swiftcord is powered by DiscordKit, a Discord API implementation in Swift - Swiftcord is powered by DiscordKit, a Discord API implementation in Swift - No comment provided by engineer. - - - Swiftcord on GitHub - Swiftcord on GitHub - No comment provided by engineer. - - - TODO - TODO - No comment provided by engineer. - - - Text & Images - Text & Images - No comment provided by engineer. - - - Thanks to all those who made valuable contributions! Swiftcord wouldn't be where it is without your contributions! - Thanks to all those who made valuable contributions! Swiftcord wouldn't be where it is without your contributions! - No comment provided by engineer. - - - Thanks to iJayTD on Reddit for recreating the Discord loading animation and agreeing to its use in Swiftcord! - Thanks to iJayTD on Reddit for recreating the Discord loading animation and agreeing to its use in Swiftcord! - No comment provided by engineer. - - - The 2 biggest pain points - The 2 biggest pain points - No comment provided by engineer. - - - This is the beginning of your direct message history with - This is the beginning of your direct message history with - No comment provided by engineer. - - - This is the start of the #%@ channel. %@ - This is the start of the #%@ channel. %@ - No comment provided by engineer. - - - This user is a webhook - This user is a webhook - No comment provided by engineer. - - - Two-Factor authentication (2FA for short) is a good way to add an extra layer of security to your Discord account to make sure that only you have the ability to log in. - Two-Factor authentication (2FA for short) is a good way to add an extra layer of security to your Discord account to make sure that only you have the ability to log in. - No comment provided by engineer. - - - USERNAME - USERNAME - No comment provided by engineer. - - - Unimplemented - Unimplemented - No comment provided by engineer. - - - Up Next - Up Next - No comment provided by engineer. - - - User - User - No comment provided by engineer. - - - User Profile - User Profile - No comment provided by engineer. - - - Value - Value - No comment provided by engineer. - - - Version %@ (Build: %@) - Version %@ (Build: %@) - No comment provided by engineer. - - - View Backup Codes - View Backup Codes - No comment provided by engineer. - - - View Sticker Pack - View Sticker Pack - No comment provided by engineer. - - - Vincent Kwok - Vincent Kwok - No comment provided by engineer. - - - Voice & Video - Voice & Video - No comment provided by engineer. - - - WEBHOOK - WEBHOOK - No comment provided by engineer. - - - Welcome to the beginning of the - Welcome to the beginning of the - No comment provided by engineer. - - - Welcome, %@, enjoy your stay! - Welcome, %@, enjoy your stay! - No comment provided by engineer. - - - What are you doing with your life? - What are you doing with your life? - No comment provided by engineer. - - - Wumpus is waiting on friends. You don't have to, though! - Wumpus is waiting on friends. You don't have to, though! - No comment provided by engineer. - - - You can use markdown and links if you'd like. - You can use markdown and links if you'd like. - No comment provided by engineer. - - - You find yourself in a strange place. You don't have access to any text channels or there are none in this server. - You find yourself in a strange place. You don't have access to any text channels or there are none in this server. - No comment provided by engineer. - - - marcprux - marcprux - No comment provided by engineer. - - - royal - royal - No comment provided by engineer. - - - selimgr - selimgr - No comment provided by engineer. - - - user.bio - ABOUT ME - No comment provided by engineer. - - - • - - No comment provided by engineer. - - - • Edited: - • Edited: - No comment provided by engineer. - - -
-
diff --git a/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Source Contents/Swiftcord/en.lproj/InfoPlist.strings b/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Source Contents/Swiftcord/en.lproj/InfoPlist.strings deleted file mode 100644 index ad9e6990..00000000 --- a/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Source Contents/Swiftcord/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,4 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "Swiftcord"; -/* Copyright (human-readable) */ -"NSHumanReadableCopyright" = "Copyright © 2022 Vincent Kwok.\nAll rights reserved."; diff --git a/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Source Contents/Swiftcord/en.lproj/Localizable.strings b/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Source Contents/Swiftcord/en.lproj/Localizable.strings deleted file mode 100644 index 9c4448f7..00000000 --- a/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/Source Contents/Swiftcord/en.lproj/Localizable.strings +++ /dev/null @@ -1,468 +0,0 @@ -/* No comment provided by engineer. */ -"" = ""; - -/* No comment provided by engineer. */ -" (edited)" = " (edited)"; - -/* No comment provided by engineer. */ -" %@ typing..." = " %@ typing..."; - -/* No comment provided by engineer. */ -" group." = " group."; - -/* No comment provided by engineer. */ -"." = "."; - -/* No comment provided by engineer. */ -"@%@" = "@%@"; - -/* No comment provided by engineer. */ -"#%@" = "#%@"; - -/* No comment provided by engineer. */ -"%@" = "%@"; - -/* No comment provided by engineer. */ -"%@ • %@" = "%@ • %@"; - -/* No comment provided by engineer. */ -"%lld Members" = "%lld Members"; - -/* No comment provided by engineer. */ -"•" = "•"; - -/* No comment provided by engineer. */ -"• Edited:" = "• Edited:"; - -/* No comment provided by engineer. */ -"$$$ 💸" = "$$$ 💸"; - -/* No comment provided by engineer. */ -"A completely native Discord client for macOS built 100% in Swift and SwiftUI. Light on your CPU and RAM." = "A completely native Discord client for macOS built 100% in Swift and SwiftUI. Light on your CPU and RAM."; - -/* No comment provided by engineer. */ -"About" = "About"; - -/* No comment provided by engineer. */ -"ABOUT ME" = "ABOUT ME"; - -/* No comment provided by engineer. */ -"Accessibility" = "Accessibility"; - -/* No comment provided by engineer. */ -"ACCOUNT REMOVAL" = "ACCOUNT REMOVAL"; - -/* No comment provided by engineer. */ -"Activity" = "Activity"; - -/* No comment provided by engineer. */ -"Activity Status" = "Activity Status"; - -/* No comment provided by engineer. */ -"Add a note to this user (only visible to you)" = "Add a note to this user (only visible to you)"; - -/* No comment provided by engineer. */ -"Add Reaction" = "Add Reaction"; - -/* No comment provided by engineer. */ -"Advanced" = "Advanced"; - -/* No comment provided by engineer. */ -"And finally, thanks to Discord for building such an amazing community and infrastructure!" = "And finally, thanks to Discord for building such an amazing community and infrastructure!"; - -/* No comment provided by engineer. */ -"Anthony Ingle" = "Anthony Ingle"; - -/* No comment provided by engineer. */ -"App" = "App"; - -/* No comment provided by engineer. */ -"Appearance" = "Appearance"; - -/* No comment provided by engineer. */ -"Append to queue" = "Append to queue"; - -/* No comment provided by engineer. */ -"Are you sure you want to log out?" = "Are you sure you want to log out?"; - -/* No comment provided by engineer. */ -"Authorized Apps" = "Authorized Apps"; - -/* No comment provided by engineer. */ -"Ben Tettmar" = "Ben Tettmar"; - -/* No comment provided by engineer. */ -"Big thanks to all contributors <3! Contributions are more than welcome :D" = "Big thanks to all contributors <3! Contributions are more than welcome :D"; - -/* No comment provided by engineer. */ -"Billing" = "Billing"; - -/* No comment provided by engineer. */ -"BOT" = "BOT"; - -/* No comment provided by engineer. */ -"Candygoblen123" = "Candygoblen123"; - -/* No comment provided by engineer. */ -"Change Log" = "Change Log"; - -/* No comment provided by engineer. */ -"Change Password" = "Change Password"; - -/* No comment provided by engineer. */ -"Change your password" = "Change your password"; - -/* No comment provided by engineer. */ -"Check for Updates…" = "Check for Updates…"; - -/* No comment provided by engineer. */ -"Click to see attachment" = "Click to see attachment"; - -/* No comment provided by engineer. */ -"Close" = "Close"; - -/* No comment provided by engineer. */ -"Connections" = "Connections"; - -/* No comment provided by engineer. */ -"Contributors" = "Contributors"; - -/* No comment provided by engineer. */ -"Copy ID" = "Copy ID"; - -/* No comment provided by engineer. */ -"Copy Link" = "Copy Link"; - -/* No comment provided by engineer. */ -"Create Thread" = "Create Thread"; - -/* No comment provided by engineer. */ -"Create/Join Server" = "Create/Join Server"; - -/* No comment provided by engineer. */ -"Credits" = "Credits"; - -/* No comment provided by engineer. */ -"Cue Discord ping sound" = "Cue Discord ping sound"; - -/* No comment provided by engineer. */ -"Debug" = "Debug"; - -/* No comment provided by engineer. */ -"Delete Account" = "Delete Account"; - -/* No comment provided by engineer. */ -"Delete Message" = "Delete Message"; - -/* No comment provided by engineer. */ -"Disable Account" = "Disable Account"; - -/* No comment provided by engineer. */ -"Disabling your account means you can recover it at any time after taking this action." = "Disabling your account means you can recover it at any time after taking this action."; - -/* No comment provided by engineer. */ -"Discord Nitro" = "Discord Nitro"; - -/* No comment provided by engineer. */ -"DMs" = "DMs"; - -/* No comment provided by engineer. */ -"Don't get nitro, nitro bad" = "Don't get nitro, nitro bad"; - -/* No comment provided by engineer. */ -"Done" = "Done"; - -/* No comment provided by engineer. */ -"Download attachment" = "Download attachment"; - -/* No comment provided by engineer. */ -"Drop file to add attachment" = "Drop file to add attachment"; - -/* No comment provided by engineer. */ -"Edit" = "Edit"; - -/* No comment provided by engineer. */ -"EMAIL" = "EMAIL"; - -/* No comment provided by engineer. */ -"Enter your current password and a new one." = "Enter your current password and a new one."; - -/* No comment provided by engineer. */ -"Failed to get full user profile" = "Failed to get full user profile"; - -/* No comment provided by engineer. */ -"Gateway isn't connected" = "Gateway isn't connected"; - -/* No comment provided by engineer. */ -"Gift Inventory" = "Gift Inventory"; - -/* No comment provided by engineer. */ -"Got It!" = "Got It!"; - -/* No comment provided by engineer. */ -"Head Developer" = "Head Developer"; - -/* No comment provided by engineer. */ -"Hello, World!" = "Hello, World!"; - -/* No comment provided by engineer. */ -"Hypesquad" = "Hypesquad"; - -/* No comment provided by engineer. */ -"Item" = "Item"; - -/* No comment provided by engineer. */ -"Keybinds" = "Keybinds"; - -/* No comment provided by engineer. */ -"Language" = "Language"; - -/* No comment provided by engineer. */ -"Loading Discord login..." = "Loading Discord login..."; - -/* No comment provided by engineer. */ -"Loading full profile..." = "Loading full profile..."; - -/* No comment provided by engineer. */ -"LOADING ROLES" = "LOADING ROLES"; - -/* No comment provided by engineer. */ -"Loading roles..." = "Loading roles..."; - -/* No comment provided by engineer. */ -"Loading sticker..." = "Loading sticker..."; - -/* No comment provided by engineer. */ -"Log Out" = "Log Out"; - -/* No comment provided by engineer. */ -"Manage Server Webhooks" = "Manage Server Webhooks"; - -/* No comment provided by engineer. */ -"marcprux" = "marcprux"; - -/* No comment provided by engineer. */ -"Media Center" = "Media Center"; - -/* No comment provided by engineer. */ -"My Account" = "My Account"; - -/* No comment provided by engineer. */ -"Navigation" = "Navigation"; - -/* No comment provided by engineer. */ -"Next Channel" = "Next Channel"; - -/* No comment provided by engineer. */ -"Next Server" = "Next Server"; - -/* No comment provided by engineer. */ -"No network connectivity" = "No network connectivity"; - -/* No comment provided by engineer. */ -"NO ROLES" = "NO ROLES"; - -/* No comment provided by engineer. */ -"No server selected" = "No server selected"; - -/* No comment provided by engineer. */ -"NO TEXT CHANNELS" = "NO TEXT CHANNELS"; - -/* No comment provided by engineer. */ -"Not hype" = "Not hype"; - -/* No comment provided by engineer. */ -"NOTE" = "NOTE"; - -/* No comment provided by engineer. */ -"Nothing" = "Nothing"; - -/* No comment provided by engineer. */ -"Nothing in queue" = "Nothing in queue"; - -/* No comment provided by engineer. */ -"Notifications" = "Notifications"; - -/* No comment provided by engineer. */ -"Original message was deleted." = "Original message was deleted."; - -/* No comment provided by engineer. */ -"Others" = "Others"; - -/* No comment provided by engineer. */ -"Password and Authenthication" = "Password and Authenthication"; - -/* No comment provided by engineer. */ -"PHONE NUMBER" = "PHONE NUMBER"; - -/* No comment provided by engineer. */ -"Pin Message" = "Pin Message"; - -/* No comment provided by engineer. */ -"Play now" = "Play now"; - -/* No comment provided by engineer. */ -"Please sponsor Swiftcord on GitHub! I'll be eternally grateful <3" = "Please sponsor Swiftcord on GitHub! I'll be eternally grateful <3"; - -/* No comment provided by engineer. */ -"PREVIEW" = "PREVIEW"; - -/* No comment provided by engineer. */ -"Preview attachment" = "Preview attachment"; - -/* No comment provided by engineer. */ -"Previous Channel" = "Previous Channel"; - -/* No comment provided by engineer. */ -"Previous Server" = "Previous Server"; - -/* No comment provided by engineer. */ -"Privacy & Safety" = "Privacy & Safety"; - -/* No comment provided by engineer. */ -"Quit" = "Quit"; - -/* No comment provided by engineer. */ -"Reconnecting..." = "Reconnecting..."; - -/* No comment provided by engineer. */ -"Remove 2FA" = "Remove 2FA"; - -/* No comment provided by engineer. */ -"Remove attachment" = "Remove attachment"; - -/* No comment provided by engineer. */ -"Reply" = "Reply"; - -/* No comment provided by engineer. */ -"ROLE" = "ROLE"; - -/* No comment provided by engineer. */ -"ROLES" = "ROLES"; - -/* No comment provided by engineer. */ -"royal" = "royal"; - -/* No comment provided by engineer. */ -"selimgr" = "selimgr"; - -/* No comment provided by engineer. */ -"Server Boost" = "Server Boost"; - -/* No comment provided by engineer. */ -"Settings can only be modified after logging in and while the gateway is connected." = "Settings can only be modified after logging in and while the gateway is connected."; - -/* No comment provided by engineer. */ -"Sorry, aPNG stickers can't be played (yet)" = "Sorry, aPNG stickers can't be played (yet)"; - -/* No comment provided by engineer. */ -"Sponsoring Swiftcord allows me to continue developing it!" = "Sponsoring Swiftcord allows me to continue developing it!"; - -/* No comment provided by engineer. */ -"Sponsors" = "Sponsors"; - -/* No comment provided by engineer. */ -"Sticker Pack" = "Sticker Pack"; - -/* No comment provided by engineer. */ -"Streamer Mode" = "Streamer Mode"; - -/* No comment provided by engineer. */ -"Subscriptions" = "Subscriptions"; - -/* No comment provided by engineer. */ -"Swiftcord" = "Swiftcord"; - -/* No comment provided by engineer. */ -"Swiftcord is open-source software and built with love. You can find its source code in GitHub at the link below! Contributions and issue reports are welcome ;) Please also give Swiftcord a star, it gives me motivation to continue working on it." = "Swiftcord is open-source software and built with love. You can find its source code in GitHub at the link below! Contributions and issue reports are welcome ;) Please also give Swiftcord a star, it gives me motivation to continue working on it."; - -/* No comment provided by engineer. */ -"Swiftcord is powered by DiscordKit, a Discord API implementation in Swift" = "Swiftcord is powered by DiscordKit, a Discord API implementation in Swift"; - -/* No comment provided by engineer. */ -"Swiftcord on GitHub" = "Swiftcord on GitHub"; - -/* No comment provided by engineer. */ -"Text & Images" = "Text & Images"; - -/* No comment provided by engineer. */ -"Thanks to all those who made valuable contributions! Swiftcord wouldn't be where it is without your contributions!" = "Thanks to all those who made valuable contributions! Swiftcord wouldn't be where it is without your contributions!"; - -/* No comment provided by engineer. */ -"Thanks to iJayTD on Reddit for recreating the Discord loading animation and agreeing to its use in Swiftcord!" = "Thanks to iJayTD on Reddit for recreating the Discord loading animation and agreeing to its use in Swiftcord!"; - -/* No comment provided by engineer. */ -"The 2 biggest pain points" = "The 2 biggest pain points"; - -/* No comment provided by engineer. */ -"This is the beginning of your direct message history with " = "This is the beginning of your direct message history with "; - -/* No comment provided by engineer. */ -"This is the start of the #%@ channel. %@" = "This is the start of the #%@ channel. %@"; - -/* No comment provided by engineer. */ -"This user is a webhook" = "This user is a webhook"; - -/* No comment provided by engineer. */ -"TODO" = "TODO"; - -/* No comment provided by engineer. */ -"Two-Factor authentication (2FA for short) is a good way to add an extra layer of security to your Discord account to make sure that only you have the ability to log in." = "Two-Factor authentication (2FA for short) is a good way to add an extra layer of security to your Discord account to make sure that only you have the ability to log in."; - -/* No comment provided by engineer. */ -"Unimplemented" = "Unimplemented"; - -/* No comment provided by engineer. */ -"Up Next" = "Up Next"; - -/* No comment provided by engineer. */ -"User" = "User"; - -/* No comment provided by engineer. */ -"User Profile" = "User Profile"; - -/* No comment provided by engineer. */ -"user.bio" = "user.bio"; - -/* No comment provided by engineer. */ -"USERNAME" = "USERNAME"; - -/* No comment provided by engineer. */ -"Value" = "Value"; - -/* No comment provided by engineer. */ -"Version %@ (Build: %@)" = "Version %@ (Build: %@)"; - -/* No comment provided by engineer. */ -"View Backup Codes" = "View Backup Codes"; - -/* No comment provided by engineer. */ -"View Sticker Pack" = "View Sticker Pack"; - -/* No comment provided by engineer. */ -"Vincent Kwok" = "Vincent Kwok"; - -/* No comment provided by engineer. */ -"Voice & Video" = "Voice & Video"; - -/* No comment provided by engineer. */ -"WEBHOOK" = "WEBHOOK"; - -/* No comment provided by engineer. */ -"Welcome to the beginning of the " = "Welcome to the beginning of the "; - -/* No comment provided by engineer. */ -"Welcome, %@, enjoy your stay!" = "Welcome, %@, enjoy your stay!"; - -/* No comment provided by engineer. */ -"What are you doing with your life?" = "What are you doing with your life?"; - -/* No comment provided by engineer. */ -"Wumpus is waiting on friends. You don't have to, though!" = "Wumpus is waiting on friends. You don't have to, though!"; - -/* No comment provided by engineer. */ -"You can use markdown and links if you'd like." = "You can use markdown and links if you'd like."; - -/* No comment provided by engineer. */ -"You find yourself in a strange place. You don't have access to any text channels or there are none in this server." = "You find yourself in a strange place. You don't have access to any text channels or there are none in this server."; - diff --git a/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/contents.json b/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/contents.json deleted file mode 100644 index dd0af29e..00000000 --- a/Swiftcord/Localizations/Swiftcord Localizations/en.xcloc/contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "developmentRegion" : "en", - "project" : "Swiftcord.xcodeproj", - "targetLocale" : "en", - "toolInfo" : { - "toolBuildNumber" : "13E500a", - "toolID" : "com.apple.dt.xcode", - "toolName" : "Xcode", - "toolVersion" : "13.3.1" - }, - "version" : "1.0" -} \ No newline at end of file diff --git a/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff b/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff deleted file mode 100644 index f787360f..00000000 --- a/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff +++ /dev/null @@ -1,674 +0,0 @@ - - - -
- -
- - - Swiftcord - Bundle name - - - Copyright © 2022 Vincent Kwok. -All rights reserved. - Copyright (human-readable) - - -
- -
- -
- - - %@ typing... - No comment provided by engineer. - - - (edited) - (已编辑) - No comment provided by engineer. - - - group. - No comment provided by engineer. - - - #%@ - No comment provided by engineer. - - - $$$ 💸 - No comment provided by engineer. - - - %@ - No comment provided by engineer. - - - %@ • %@ - No comment provided by engineer. - - - %lld Members - No comment provided by engineer. - - - . - No comment provided by engineer. - - - @%@ - No comment provided by engineer. - - - A completely native Discord client for macOS built 100% in Swift and SwiftUI. Light on your CPU and RAM. - No comment provided by engineer. - - - ABOUT ME - No comment provided by engineer. - - - ACCOUNT REMOVAL - No comment provided by engineer. - - - About - No comment provided by engineer. - - - Accessibility - No comment provided by engineer. - - - Activity - No comment provided by engineer. - - - Activity Status - No comment provided by engineer. - - - Add Reaction - No comment provided by engineer. - - - Add a note to this user (only visible to you) - No comment provided by engineer. - - - Advanced - No comment provided by engineer. - - - And finally, thanks to Discord for building such an amazing community and infrastructure! - No comment provided by engineer. - - - Anthony Ingle - No comment provided by engineer. - - - App - No comment provided by engineer. - - - Appearance - 外观 - No comment provided by engineer. - - - Append to queue - No comment provided by engineer. - - - Are you sure you want to log out? - No comment provided by engineer. - - - Authorized Apps - No comment provided by engineer. - - - BOT - No comment provided by engineer. - - - Ben Tettmar - No comment provided by engineer. - - - Big thanks to all contributors <3! Contributions are more than welcome :D - No comment provided by engineer. - - - Billing - No comment provided by engineer. - - - Candygoblen123 - No comment provided by engineer. - - - Change Log - No comment provided by engineer. - - - Change Password - No comment provided by engineer. - - - Change your password - No comment provided by engineer. - - - Check for Updates… - No comment provided by engineer. - - - Click to see attachment - No comment provided by engineer. - - - Close - No comment provided by engineer. - - - Connections - 连接​​​​​​​​ - No comment provided by engineer. - - - Contributors - No comment provided by engineer. - - - Copy ID - 复制 ID - No comment provided by engineer. - - - Copy Link - 复制链接 - No comment provided by engineer. - - - Create Thread - 创建子区 - No comment provided by engineer. - - - Create/Join Server - No comment provided by engineer. - - - Credits - No comment provided by engineer. - - - Cue Discord ping sound - No comment provided by engineer. - - - DMs - No comment provided by engineer. - - - Debug - No comment provided by engineer. - - - Delete Account - No comment provided by engineer. - - - Delete Message - No comment provided by engineer. - - - Disable Account - No comment provided by engineer. - - - Disabling your account means you can recover it at any time after taking this action. - No comment provided by engineer. - - - Discord Nitro - Nitro - No comment provided by engineer. - - - Don't get nitro, nitro bad - No comment provided by engineer. - - - Done - 编辑信息 - No comment provided by engineer. - - - Download attachment - No comment provided by engineer. - - - Drop file to add attachment - No comment provided by engineer. - - - EMAIL - No comment provided by engineer. - - - Edit - No comment provided by engineer. - - - Enter your current password and a new one. - No comment provided by engineer. - - - Failed to get full user profile - No comment provided by engineer. - - - Gateway isn't connected - No comment provided by engineer. - - - Gift Inventory - No comment provided by engineer. - - - Got It! - No comment provided by engineer. - - - Head Developer - No comment provided by engineer. - - - Hello, World! - No comment provided by engineer. - - - Hypesquad - No comment provided by engineer. - - - Item - No comment provided by engineer. - - - Keybinds - No comment provided by engineer. - - - LOADING ROLES - No comment provided by engineer. - - - Language - No comment provided by engineer. - - - Loading Discord login... - No comment provided by engineer. - - - Loading full profile... - No comment provided by engineer. - - - Loading roles... - No comment provided by engineer. - - - Loading sticker... - No comment provided by engineer. - - - Log Out - 登出 - No comment provided by engineer. - - - Manage Server Webhooks - No comment provided by engineer. - - - Media Center - No comment provided by engineer. - - - My Account - 我的账号 - No comment provided by engineer. - - - NO ROLES - 没有身份组 - No comment provided by engineer. - - - NO TEXT CHANNELS - 无文字频道 - No comment provided by engineer. - - - NOTE - 备注 - No comment provided by engineer. - - - Navigation - 导航 - No comment provided by engineer. - - - Next Channel - 下个起点 - No comment provided by engineer. - - - Next Server - No comment provided by engineer. - - - No network connectivity - No comment provided by engineer. - - - No server selected - No comment provided by engineer. - - - Not hype - No comment provided by engineer. - - - Nothing - No comment provided by engineer. - - - Nothing in queue - No comment provided by engineer. - - - Notifications - No comment provided by engineer. - - - Original message was deleted. - 原始消息已被删除。 - No comment provided by engineer. - - - Others - No comment provided by engineer. - - - PHONE NUMBER - No comment provided by engineer. - - - PREVIEW - No comment provided by engineer. - - - Password and Authenthication - No comment provided by engineer. - - - Pin Message - No comment provided by engineer. - - - Play now - No comment provided by engineer. - - - - Preview attachment - No comment provided by engineer. - - - Previous Channel - 前个起点 - No comment provided by engineer. - - - Previous Server - No comment provided by engineer. - - - Privacy & Safety - 隐私与安全 - No comment provided by engineer. - - - Quit - No comment provided by engineer. - - - ROLE - 身份组 - No comment provided by engineer. - - - ROLES - 身份组 - No comment provided by engineer. - - - Reconnecting... - No comment provided by engineer. - - - Remove 2FA - No comment provided by engineer. - - - Remove attachment - 移除附件 - No comment provided by engineer. - - - Reply - 回复 - No comment provided by engineer. - - - Server Boost - 服务器助力 - No comment provided by engineer. - - - Settings can only be modified after logging in and while the gateway is connected. - No comment provided by engineer. - - - Sorry, aPNG stickers can't be played (yet) - No comment provided by engineer. - - - Sponsoring Swiftcord allows me to continue developing it! - No comment provided by engineer. - - - Sponsors - No comment provided by engineer. - - - Sticker Pack - No comment provided by engineer. - - - Streamer Mode - No comment provided by engineer. - - - Subscriptions - No comment provided by engineer. - - - Swiftcord - No comment provided by engineer. - - - Swiftcord is open-source software and built with love. You can find its source code in GitHub at the link below! Contributions and issue reports are welcome ;) Please also give Swiftcord a star, it gives me motivation to continue working on it. - No comment provided by engineer. - - - Swiftcord is powered by DiscordKit, a Discord API implementation in Swift - No comment provided by engineer. - - - Swiftcord on GitHub - No comment provided by engineer. - - - TODO - No comment provided by engineer. - - - Text & Images - No comment provided by engineer. - - - Thanks to all those who made valuable contributions! Swiftcord wouldn't be where it is without your contributions! - No comment provided by engineer. - - - Thanks to iJayTD on Reddit for recreating the Discord loading animation and agreeing to its use in Swiftcord! - No comment provided by engineer. - - - The 2 biggest pain points - No comment provided by engineer. - - - This is the beginning of your direct message history with - No comment provided by engineer. - - - This is the start of the #%@ channel. %@ - 这是 #%@ 频道的起点。%@ - No comment provided by engineer. - - - This user is a webhook - No comment provided by engineer. - - - Two-Factor authentication (2FA for short) is a good way to add an extra layer of security to your Discord account to make sure that only you have the ability to log in. - No comment provided by engineer. - - - USERNAME - No comment provided by engineer. - - - Unimplemented - No comment provided by engineer. - - - Up Next - No comment provided by engineer. - - - User - No comment provided by engineer. - - - User Profile - 用户个人资料 - No comment provided by engineer. - - - Value - No comment provided by engineer. - - - Version %@ (Build: %@) - No comment provided by engineer. - - - View Backup Codes - No comment provided by engineer. - - - View Sticker Pack - No comment provided by engineer. - - - Vincent Kwok - No comment provided by engineer. - - - Voice & Video - No comment provided by engineer. - - - WEBHOOK - No comment provided by engineer. - - - Welcome to the beginning of the - No comment provided by engineer. - - - Welcome, %@, enjoy your stay! - No comment provided by engineer. - - - What are you doing with your life? - No comment provided by engineer. - - - Wumpus is waiting on friends. You don't have to, though! - Wumpus在苦等自己的朋友。不过您不用等哦! - No comment provided by engineer. - - - You can use markdown and links if you'd like. - No comment provided by engineer. - - - You find yourself in a strange place. You don't have access to any text channels or there are none in this server. - 您发现您身处一个奇怪的地方。您没有权限访问任何文字频道,或者此服务器上没有文字频道。 - No comment provided by engineer. - - - marcprux - No comment provided by engineer. - - - royal - No comment provided by engineer. - - - selimgr - No comment provided by engineer. - - - user.bio - 自我介绍 - No comment provided by engineer. - - - • - No comment provided by engineer. - - - • Edited: - No comment provided by engineer. - - -
-
diff --git a/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Source Contents/Swiftcord/en.lproj/InfoPlist.strings b/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Source Contents/Swiftcord/en.lproj/InfoPlist.strings deleted file mode 100644 index ad9e6990..00000000 --- a/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Source Contents/Swiftcord/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,4 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "Swiftcord"; -/* Copyright (human-readable) */ -"NSHumanReadableCopyright" = "Copyright © 2022 Vincent Kwok.\nAll rights reserved."; diff --git a/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Source Contents/Swiftcord/en.lproj/Localizable.strings b/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Source Contents/Swiftcord/en.lproj/Localizable.strings deleted file mode 100644 index 9c4448f7..00000000 --- a/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/Source Contents/Swiftcord/en.lproj/Localizable.strings +++ /dev/null @@ -1,468 +0,0 @@ -/* No comment provided by engineer. */ -"" = ""; - -/* No comment provided by engineer. */ -" (edited)" = " (edited)"; - -/* No comment provided by engineer. */ -" %@ typing..." = " %@ typing..."; - -/* No comment provided by engineer. */ -" group." = " group."; - -/* No comment provided by engineer. */ -"." = "."; - -/* No comment provided by engineer. */ -"@%@" = "@%@"; - -/* No comment provided by engineer. */ -"#%@" = "#%@"; - -/* No comment provided by engineer. */ -"%@" = "%@"; - -/* No comment provided by engineer. */ -"%@ • %@" = "%@ • %@"; - -/* No comment provided by engineer. */ -"%lld Members" = "%lld Members"; - -/* No comment provided by engineer. */ -"•" = "•"; - -/* No comment provided by engineer. */ -"• Edited:" = "• Edited:"; - -/* No comment provided by engineer. */ -"$$$ 💸" = "$$$ 💸"; - -/* No comment provided by engineer. */ -"A completely native Discord client for macOS built 100% in Swift and SwiftUI. Light on your CPU and RAM." = "A completely native Discord client for macOS built 100% in Swift and SwiftUI. Light on your CPU and RAM."; - -/* No comment provided by engineer. */ -"About" = "About"; - -/* No comment provided by engineer. */ -"ABOUT ME" = "ABOUT ME"; - -/* No comment provided by engineer. */ -"Accessibility" = "Accessibility"; - -/* No comment provided by engineer. */ -"ACCOUNT REMOVAL" = "ACCOUNT REMOVAL"; - -/* No comment provided by engineer. */ -"Activity" = "Activity"; - -/* No comment provided by engineer. */ -"Activity Status" = "Activity Status"; - -/* No comment provided by engineer. */ -"Add a note to this user (only visible to you)" = "Add a note to this user (only visible to you)"; - -/* No comment provided by engineer. */ -"Add Reaction" = "Add Reaction"; - -/* No comment provided by engineer. */ -"Advanced" = "Advanced"; - -/* No comment provided by engineer. */ -"And finally, thanks to Discord for building such an amazing community and infrastructure!" = "And finally, thanks to Discord for building such an amazing community and infrastructure!"; - -/* No comment provided by engineer. */ -"Anthony Ingle" = "Anthony Ingle"; - -/* No comment provided by engineer. */ -"App" = "App"; - -/* No comment provided by engineer. */ -"Appearance" = "Appearance"; - -/* No comment provided by engineer. */ -"Append to queue" = "Append to queue"; - -/* No comment provided by engineer. */ -"Are you sure you want to log out?" = "Are you sure you want to log out?"; - -/* No comment provided by engineer. */ -"Authorized Apps" = "Authorized Apps"; - -/* No comment provided by engineer. */ -"Ben Tettmar" = "Ben Tettmar"; - -/* No comment provided by engineer. */ -"Big thanks to all contributors <3! Contributions are more than welcome :D" = "Big thanks to all contributors <3! Contributions are more than welcome :D"; - -/* No comment provided by engineer. */ -"Billing" = "Billing"; - -/* No comment provided by engineer. */ -"BOT" = "BOT"; - -/* No comment provided by engineer. */ -"Candygoblen123" = "Candygoblen123"; - -/* No comment provided by engineer. */ -"Change Log" = "Change Log"; - -/* No comment provided by engineer. */ -"Change Password" = "Change Password"; - -/* No comment provided by engineer. */ -"Change your password" = "Change your password"; - -/* No comment provided by engineer. */ -"Check for Updates…" = "Check for Updates…"; - -/* No comment provided by engineer. */ -"Click to see attachment" = "Click to see attachment"; - -/* No comment provided by engineer. */ -"Close" = "Close"; - -/* No comment provided by engineer. */ -"Connections" = "Connections"; - -/* No comment provided by engineer. */ -"Contributors" = "Contributors"; - -/* No comment provided by engineer. */ -"Copy ID" = "Copy ID"; - -/* No comment provided by engineer. */ -"Copy Link" = "Copy Link"; - -/* No comment provided by engineer. */ -"Create Thread" = "Create Thread"; - -/* No comment provided by engineer. */ -"Create/Join Server" = "Create/Join Server"; - -/* No comment provided by engineer. */ -"Credits" = "Credits"; - -/* No comment provided by engineer. */ -"Cue Discord ping sound" = "Cue Discord ping sound"; - -/* No comment provided by engineer. */ -"Debug" = "Debug"; - -/* No comment provided by engineer. */ -"Delete Account" = "Delete Account"; - -/* No comment provided by engineer. */ -"Delete Message" = "Delete Message"; - -/* No comment provided by engineer. */ -"Disable Account" = "Disable Account"; - -/* No comment provided by engineer. */ -"Disabling your account means you can recover it at any time after taking this action." = "Disabling your account means you can recover it at any time after taking this action."; - -/* No comment provided by engineer. */ -"Discord Nitro" = "Discord Nitro"; - -/* No comment provided by engineer. */ -"DMs" = "DMs"; - -/* No comment provided by engineer. */ -"Don't get nitro, nitro bad" = "Don't get nitro, nitro bad"; - -/* No comment provided by engineer. */ -"Done" = "Done"; - -/* No comment provided by engineer. */ -"Download attachment" = "Download attachment"; - -/* No comment provided by engineer. */ -"Drop file to add attachment" = "Drop file to add attachment"; - -/* No comment provided by engineer. */ -"Edit" = "Edit"; - -/* No comment provided by engineer. */ -"EMAIL" = "EMAIL"; - -/* No comment provided by engineer. */ -"Enter your current password and a new one." = "Enter your current password and a new one."; - -/* No comment provided by engineer. */ -"Failed to get full user profile" = "Failed to get full user profile"; - -/* No comment provided by engineer. */ -"Gateway isn't connected" = "Gateway isn't connected"; - -/* No comment provided by engineer. */ -"Gift Inventory" = "Gift Inventory"; - -/* No comment provided by engineer. */ -"Got It!" = "Got It!"; - -/* No comment provided by engineer. */ -"Head Developer" = "Head Developer"; - -/* No comment provided by engineer. */ -"Hello, World!" = "Hello, World!"; - -/* No comment provided by engineer. */ -"Hypesquad" = "Hypesquad"; - -/* No comment provided by engineer. */ -"Item" = "Item"; - -/* No comment provided by engineer. */ -"Keybinds" = "Keybinds"; - -/* No comment provided by engineer. */ -"Language" = "Language"; - -/* No comment provided by engineer. */ -"Loading Discord login..." = "Loading Discord login..."; - -/* No comment provided by engineer. */ -"Loading full profile..." = "Loading full profile..."; - -/* No comment provided by engineer. */ -"LOADING ROLES" = "LOADING ROLES"; - -/* No comment provided by engineer. */ -"Loading roles..." = "Loading roles..."; - -/* No comment provided by engineer. */ -"Loading sticker..." = "Loading sticker..."; - -/* No comment provided by engineer. */ -"Log Out" = "Log Out"; - -/* No comment provided by engineer. */ -"Manage Server Webhooks" = "Manage Server Webhooks"; - -/* No comment provided by engineer. */ -"marcprux" = "marcprux"; - -/* No comment provided by engineer. */ -"Media Center" = "Media Center"; - -/* No comment provided by engineer. */ -"My Account" = "My Account"; - -/* No comment provided by engineer. */ -"Navigation" = "Navigation"; - -/* No comment provided by engineer. */ -"Next Channel" = "Next Channel"; - -/* No comment provided by engineer. */ -"Next Server" = "Next Server"; - -/* No comment provided by engineer. */ -"No network connectivity" = "No network connectivity"; - -/* No comment provided by engineer. */ -"NO ROLES" = "NO ROLES"; - -/* No comment provided by engineer. */ -"No server selected" = "No server selected"; - -/* No comment provided by engineer. */ -"NO TEXT CHANNELS" = "NO TEXT CHANNELS"; - -/* No comment provided by engineer. */ -"Not hype" = "Not hype"; - -/* No comment provided by engineer. */ -"NOTE" = "NOTE"; - -/* No comment provided by engineer. */ -"Nothing" = "Nothing"; - -/* No comment provided by engineer. */ -"Nothing in queue" = "Nothing in queue"; - -/* No comment provided by engineer. */ -"Notifications" = "Notifications"; - -/* No comment provided by engineer. */ -"Original message was deleted." = "Original message was deleted."; - -/* No comment provided by engineer. */ -"Others" = "Others"; - -/* No comment provided by engineer. */ -"Password and Authenthication" = "Password and Authenthication"; - -/* No comment provided by engineer. */ -"PHONE NUMBER" = "PHONE NUMBER"; - -/* No comment provided by engineer. */ -"Pin Message" = "Pin Message"; - -/* No comment provided by engineer. */ -"Play now" = "Play now"; - -/* No comment provided by engineer. */ -"Please sponsor Swiftcord on GitHub! I'll be eternally grateful <3" = "Please sponsor Swiftcord on GitHub! I'll be eternally grateful <3"; - -/* No comment provided by engineer. */ -"PREVIEW" = "PREVIEW"; - -/* No comment provided by engineer. */ -"Preview attachment" = "Preview attachment"; - -/* No comment provided by engineer. */ -"Previous Channel" = "Previous Channel"; - -/* No comment provided by engineer. */ -"Previous Server" = "Previous Server"; - -/* No comment provided by engineer. */ -"Privacy & Safety" = "Privacy & Safety"; - -/* No comment provided by engineer. */ -"Quit" = "Quit"; - -/* No comment provided by engineer. */ -"Reconnecting..." = "Reconnecting..."; - -/* No comment provided by engineer. */ -"Remove 2FA" = "Remove 2FA"; - -/* No comment provided by engineer. */ -"Remove attachment" = "Remove attachment"; - -/* No comment provided by engineer. */ -"Reply" = "Reply"; - -/* No comment provided by engineer. */ -"ROLE" = "ROLE"; - -/* No comment provided by engineer. */ -"ROLES" = "ROLES"; - -/* No comment provided by engineer. */ -"royal" = "royal"; - -/* No comment provided by engineer. */ -"selimgr" = "selimgr"; - -/* No comment provided by engineer. */ -"Server Boost" = "Server Boost"; - -/* No comment provided by engineer. */ -"Settings can only be modified after logging in and while the gateway is connected." = "Settings can only be modified after logging in and while the gateway is connected."; - -/* No comment provided by engineer. */ -"Sorry, aPNG stickers can't be played (yet)" = "Sorry, aPNG stickers can't be played (yet)"; - -/* No comment provided by engineer. */ -"Sponsoring Swiftcord allows me to continue developing it!" = "Sponsoring Swiftcord allows me to continue developing it!"; - -/* No comment provided by engineer. */ -"Sponsors" = "Sponsors"; - -/* No comment provided by engineer. */ -"Sticker Pack" = "Sticker Pack"; - -/* No comment provided by engineer. */ -"Streamer Mode" = "Streamer Mode"; - -/* No comment provided by engineer. */ -"Subscriptions" = "Subscriptions"; - -/* No comment provided by engineer. */ -"Swiftcord" = "Swiftcord"; - -/* No comment provided by engineer. */ -"Swiftcord is open-source software and built with love. You can find its source code in GitHub at the link below! Contributions and issue reports are welcome ;) Please also give Swiftcord a star, it gives me motivation to continue working on it." = "Swiftcord is open-source software and built with love. You can find its source code in GitHub at the link below! Contributions and issue reports are welcome ;) Please also give Swiftcord a star, it gives me motivation to continue working on it."; - -/* No comment provided by engineer. */ -"Swiftcord is powered by DiscordKit, a Discord API implementation in Swift" = "Swiftcord is powered by DiscordKit, a Discord API implementation in Swift"; - -/* No comment provided by engineer. */ -"Swiftcord on GitHub" = "Swiftcord on GitHub"; - -/* No comment provided by engineer. */ -"Text & Images" = "Text & Images"; - -/* No comment provided by engineer. */ -"Thanks to all those who made valuable contributions! Swiftcord wouldn't be where it is without your contributions!" = "Thanks to all those who made valuable contributions! Swiftcord wouldn't be where it is without your contributions!"; - -/* No comment provided by engineer. */ -"Thanks to iJayTD on Reddit for recreating the Discord loading animation and agreeing to its use in Swiftcord!" = "Thanks to iJayTD on Reddit for recreating the Discord loading animation and agreeing to its use in Swiftcord!"; - -/* No comment provided by engineer. */ -"The 2 biggest pain points" = "The 2 biggest pain points"; - -/* No comment provided by engineer. */ -"This is the beginning of your direct message history with " = "This is the beginning of your direct message history with "; - -/* No comment provided by engineer. */ -"This is the start of the #%@ channel. %@" = "This is the start of the #%@ channel. %@"; - -/* No comment provided by engineer. */ -"This user is a webhook" = "This user is a webhook"; - -/* No comment provided by engineer. */ -"TODO" = "TODO"; - -/* No comment provided by engineer. */ -"Two-Factor authentication (2FA for short) is a good way to add an extra layer of security to your Discord account to make sure that only you have the ability to log in." = "Two-Factor authentication (2FA for short) is a good way to add an extra layer of security to your Discord account to make sure that only you have the ability to log in."; - -/* No comment provided by engineer. */ -"Unimplemented" = "Unimplemented"; - -/* No comment provided by engineer. */ -"Up Next" = "Up Next"; - -/* No comment provided by engineer. */ -"User" = "User"; - -/* No comment provided by engineer. */ -"User Profile" = "User Profile"; - -/* No comment provided by engineer. */ -"user.bio" = "user.bio"; - -/* No comment provided by engineer. */ -"USERNAME" = "USERNAME"; - -/* No comment provided by engineer. */ -"Value" = "Value"; - -/* No comment provided by engineer. */ -"Version %@ (Build: %@)" = "Version %@ (Build: %@)"; - -/* No comment provided by engineer. */ -"View Backup Codes" = "View Backup Codes"; - -/* No comment provided by engineer. */ -"View Sticker Pack" = "View Sticker Pack"; - -/* No comment provided by engineer. */ -"Vincent Kwok" = "Vincent Kwok"; - -/* No comment provided by engineer. */ -"Voice & Video" = "Voice & Video"; - -/* No comment provided by engineer. */ -"WEBHOOK" = "WEBHOOK"; - -/* No comment provided by engineer. */ -"Welcome to the beginning of the " = "Welcome to the beginning of the "; - -/* No comment provided by engineer. */ -"Welcome, %@, enjoy your stay!" = "Welcome, %@, enjoy your stay!"; - -/* No comment provided by engineer. */ -"What are you doing with your life?" = "What are you doing with your life?"; - -/* No comment provided by engineer. */ -"Wumpus is waiting on friends. You don't have to, though!" = "Wumpus is waiting on friends. You don't have to, though!"; - -/* No comment provided by engineer. */ -"You can use markdown and links if you'd like." = "You can use markdown and links if you'd like."; - -/* No comment provided by engineer. */ -"You find yourself in a strange place. You don't have access to any text channels or there are none in this server." = "You find yourself in a strange place. You don't have access to any text channels or there are none in this server."; - diff --git a/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/contents.json b/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/contents.json deleted file mode 100644 index 2e766cb4..00000000 --- a/Swiftcord/Localizations/Swiftcord Localizations/zh-Hans.xcloc/contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "developmentRegion" : "en", - "project" : "Swiftcord.xcodeproj", - "targetLocale" : "zh-Hans", - "toolInfo" : { - "toolBuildNumber" : "13E500a", - "toolID" : "com.apple.dt.xcode", - "toolName" : "Xcode", - "toolVersion" : "13.3.1" - }, - "version" : "1.0" -} \ No newline at end of file From a11ccd940c3ef74c53b42eb7df7a9c1da4f5ae15 Mon Sep 17 00:00:00 2001 From: vinkwok Date: Thu, 7 Jul 2022 20:37:56 +0800 Subject: [PATCH 53/56] Fix hardcoded version string for getting release notes --- Swiftcord/Views/ContentView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Swiftcord/Views/ContentView.swift b/Swiftcord/Views/ContentView.swift index 6d30023d..8f646109 100644 --- a/Swiftcord/Views/ContentView.swift +++ b/Swiftcord/Views/ContentView.swift @@ -154,7 +154,7 @@ struct ContentView: View { Task { do { whatsNewMarkdown = try await GitHubAPI - .getReleaseByTag(org: "SwiftcordApp", repo: "Swiftcord", tag: "v0.4.1") + .getReleaseByTag(org: "SwiftcordApp", repo: "Swiftcord", tag: "v\(Bundle.main.infoDictionary!["CFBundleShortVersionString"] ?? "")") .body } catch { skipWhatsNew = true From 01b2475d66aee94b2d42c893935a17f898a90cce Mon Sep 17 00:00:00 2001 From: vinkwok Date: Fri, 8 Jul 2022 21:59:00 +0800 Subject: [PATCH 54/56] Fix wrong padding for App Store icon --- .../AppIcon.appiconset/Contents.json | 2 +- .../AppIcon.appiconset/Picture 1.png | Bin 0 -> 307462 bytes .../AppIcon.appiconset/app-512@2x.png | Bin 123844 -> 0 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 Swiftcord/Assets.xcassets/AppIcon.appiconset/Picture 1.png delete mode 100644 Swiftcord/Assets.xcassets/AppIcon.appiconset/app-512@2x.png diff --git a/Swiftcord/Assets.xcassets/AppIcon.appiconset/Contents.json b/Swiftcord/Assets.xcassets/AppIcon.appiconset/Contents.json index a2f58b31..483078f4 100644 --- a/Swiftcord/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Swiftcord/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -55,7 +55,7 @@ "size" : "512x512" }, { - "filename" : "app-512@2x.png", + "filename" : "Picture 1.png", "idiom" : "mac", "scale" : "2x", "size" : "512x512" diff --git a/Swiftcord/Assets.xcassets/AppIcon.appiconset/Picture 1.png b/Swiftcord/Assets.xcassets/AppIcon.appiconset/Picture 1.png new file mode 100644 index 0000000000000000000000000000000000000000..6c9750d0e1a17f67370e756fcbf7177ab6ff3fdd GIT binary patch literal 307462 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
9VSm^=n$`Z(d591H)f<>H7DtVT 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�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 Vnn_Ozbx;uaxVaoVe208G<=^>9X0reQ From 636cc33f7e7f7ecc6d204f904687c1fa049ea098 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Fri, 8 Jul 2022 14:18:04 +0000 Subject: [PATCH 55/56] Skip installing swiftlint --- .gitignore | 3 ++- ci_scripts/ci_post_clone.sh | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 21166e6f..3bf4f7c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -xcuserdata/ \ No newline at end of file +xcuserdata/ +.devcontainer/ \ No newline at end of file diff --git a/ci_scripts/ci_post_clone.sh b/ci_scripts/ci_post_clone.sh index cb342983..7c308a29 100755 --- a/ci_scripts/ci_post_clone.sh +++ b/ci_scripts/ci_post_clone.sh @@ -2,9 +2,9 @@ # Install AppCenter-CLI mkdir -p /Users/local/Homebrew/Cellar/node-16/16/ -curl https://nodejs.org/download/release/latest-gallium/node-v16.15.1-darwin-x64.tar.xz --output node-16.tar.gz +curl https://nodejs.org/dist/v16.16.0/node-v16.16.0-darwin-x64.tar.gz --output node-16.tar.gz tar -xf node-16.tar.gz -C /Users/local/Homebrew/Cellar/node-16/16/ --strip-components=1 brew link node-16 -brew install swiftlint \ No newline at end of file +# brew install swiftlint \ No newline at end of file From 6e994711cea62116de96632b719bfe64c2a23bdf Mon Sep 17 00:00:00 2001 From: CryptoAlgo-Dev <64193267+cryptoAlgorithm@users.noreply.github.com> Date: Fri, 8 Jul 2022 22:27:13 +0800 Subject: [PATCH 56/56] Update README (#73) * Skip installing swiftlint * Update readme, remove contributing guidelines * Create CONTRIBUTING.md Co-authored-by: Andrew Glaze --- CONTRIBUTING.md | 15 +++++++++++++++ README.md | 34 +++++++++++----------------------- 2 files changed, 26 insertions(+), 23 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..23dcfea4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,15 @@ +# Contributing + +Thank you for popping by! If you know the Discord API well, +have Swift knowledge, and feel like contributing, feel free to +make a pull request! Any (positive) contribution is welcome, +no matter how small! You can also join the Swiftcord Discord server +to discuss improvements and bug fixes! + +Found an issue? Ensure it isn't a duplicate, then open a new issue +with the appropriate template and fill in the placeholders as +clearly as you can. Responding promptly to follow-up comments +is appreciated, as debugging is hard without any further input +from the OP. + +Want to translate Swiftcord into another language? Head on over to our [Weblate](https://hosted.weblate.org/projects/swiftcord/swiftcord/)! diff --git a/README.md b/README.md index 816b6ede..44515d75 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ - +

-# Swiftcord -A completely native Discord client for macOS built 100% in Swift and SwiftUI +

Swiftcord

+

A completely native Discord client for macOS built 100% in Swift and SwiftUI

-![Viewing the general-talk channel in the r/MacBookPro server in Swiftcord](README_Resources/heroScreenshot.png) +Viewing the general-talk channel in the r/MacBookPro server in Swiftcord [![Lines of code](https://img.shields.io/tokei/lines/github/SwiftcordApp/Swiftcord?style=for-the-badge)]() [![Discord](https://img.shields.io/discord/964741354112577557?color=rgb%2888%2C101%2C242%29&label=discord&style=for-the-badge)](https://discord.gg/he7n6MGDXS) @@ -11,6 +11,8 @@ A completely native Discord client for macOS built 100% in Swift and SwiftUI [![GitHub Sponsors](https://img.shields.io/github/sponsors/cryptoAlgorithm?label=buy%20me%20a%20coffee&logo=buymeacoffee&style=for-the-badge)](https://github.com/sponsors/cryptoAlgorithm) [![Weblate project translated](https://img.shields.io/weblate/progress/swiftcord?style=for-the-badge)](https://hosted.weblate.org/projects/swiftcord/swiftcord/) +--- + This project aims to create a fully functional native Discord client in Swift for macOS from scratch. @@ -21,6 +23,7 @@ the Discord API implementation Swiftcord relies on. me to continue developing it** **Consider buying me a coffee ☕️ by sponsoring Swiftcord!** +![image](https://user-images.githubusercontent.com/64193267/178003528-eaea4288-ce49-468b-a838-12616441237f.png) ## Contents * [Motivation](#motivation) @@ -28,7 +31,6 @@ me to continue developing it** * [FAQ](#faq) * [Current State](#current-state) * [Roadmap](#roadmap) -* [Contributions](#contributions) - Read this before contributing * [Copyright Notice](#copyright-notice) --- @@ -61,6 +63,10 @@ Alpha releases are available at [GitHub Releases](https://github.com/cryptoAlgor Swiftcord is also available on homebrew as a cask: `brew install swiftcord`. Versions are lock stepped with alpha releases on GitHub releases. +### TestFlight + +Coming soon! + ### Requirements @@ -169,24 +175,6 @@ and they may not necessarily be implemented in sequence. --- -## Contributions - -Thank you for popping by! If you know the Discord API well, -have Swift knowledge, and feel like contributing, feel free to -make a pull request! Any (positive) contribution is welcome, -no matter how small! You can also join the Swiftcord Discord server -to discuss improvements and bug fixes! - -Found an issue? Ensure it isn't a duplicate, then open a new issue -with the appropriate template and fill in the placeholders as -clearly as you can. Responding promptly to follow-up comments -is appreciated, as debugging is hard without any further input -from the OP. - -Want to translate Swiftcord into another language? Head on over to our [Weblate.](https://hosted.weblate.org/projects/swiftcord/swiftcord/) - ---- - ## Copyright Notice Copyright (c) 2022 Vincent Kwok