diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 0000000..cd06bb6 --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,14 @@ +disabled_rules: + # Rule identifiers turned on by default to exclude from running + - colon + - comma + - control_statement + # Custom rule identifiers + - line_length + - type_body_length + - todo + - for_where + - file_length + - nesting + - redundant_string_enum_value + - identifier_name \ No newline at end of file diff --git a/Approval.swift b/Approval.swift deleted file mode 100644 index 9cfaa01..0000000 --- a/Approval.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// Approval.swift -// GitLab -// -// Created by Stef Kors on 21/10/2021. -// - -import Foundation - -// MARK: - Approval -struct Approval { - let id, iid, projectID: Int - let title, approvalDescription, state, createdAt: String - let updatedAt, mergeStatus: String - let approved: Bool - let approvalsRequired, approvalsLeft: Int - let requirePasswordToApprove: Bool - let approvedBy: [ApprovedBy] - let suggestedApprovers, approvers, approverGroups: [Any?] - let userHasApproved, userCanApprove: Bool - let approvalRulesLeft: [Any?] - let hasApprovalRules, mergeRequestApproversAvailable, multipleApprovalRulesAvailable: Bool -} - -// MARK: - ApprovedBy -struct ApprovedBy: Codable { - let user: Author -} diff --git a/DesktopWidgetTool/DesktopWidgetTool.swift b/DesktopWidgetTool/DesktopWidgetTool.swift index 3f98316..8dd35c1 100644 --- a/DesktopWidgetTool/DesktopWidgetTool.swift +++ b/DesktopWidgetTool/DesktopWidgetTool.swift @@ -24,12 +24,8 @@ struct Provider: TimelineProvider { ) } - init(selectedView: QueryType) { - self.selectedView = selectedView - } - // TODO: demo data? or at placeholder? - func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { + func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> Void) { Task { @MainActor in let now = Date.now @@ -48,7 +44,7 @@ struct Provider: TimelineProvider { let entry = SimpleEntry( date: now, - mergeRequests: mergeRequests, //Array(mergeRequests.prefix(5)), + mergeRequests: mergeRequests, // Array(mergeRequests.prefix(5)), accounts: accounts, repos: repos, selectedView: selectedView @@ -57,7 +53,7 @@ struct Provider: TimelineProvider { } } - func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { + func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { Task { @MainActor in var entries: [SimpleEntry] = [] @@ -83,18 +79,18 @@ struct Provider: TimelineProvider { // moreRepos.append(contentsOf: repos) // moreRepos.append(contentsOf: repos) - //let mergeRequests = ( + // let mergeRequests = ( // try? context.fetch( // FetchDescriptor(predicate: #Predicate { // $0.type == type // }) // ) - //) ?? [] + // ) ?? [] entries.append( SimpleEntry( date: now, - mergeRequests: mergeRequests, //Array(mergeRequests.prefix(5)), + mergeRequests: mergeRequests, // Array(mergeRequests.prefix(5)), accounts: accounts, repos: repos, selectedView: selectedView @@ -155,7 +151,6 @@ struct ReviewRequestedMergeRequestWidget: Widget { } } - struct LaunchPadWidget: Widget { var body: some WidgetConfiguration { StaticConfiguration(kind: "LaunchpadWidget", provider: Provider(selectedView: .authoredMergeRequests)) { entry in @@ -169,4 +164,3 @@ struct LaunchPadWidget: Widget { .supportedFamilies([.systemSmall, .systemMedium]) } } - diff --git a/DesktopWidgetTool/LaunchPadWidget/LaunchPadWidgetEntryView.swift b/DesktopWidgetTool/LaunchPadWidget/LaunchPadWidgetEntryView.swift index 20aa970..6d9af8d 100644 --- a/DesktopWidgetTool/LaunchPadWidget/LaunchPadWidgetEntryView.swift +++ b/DesktopWidgetTool/LaunchPadWidget/LaunchPadWidgetEntryView.swift @@ -8,7 +8,7 @@ import SwiftUI import WidgetKit -struct LaunchPadWidgetEntryView : View { +struct LaunchPadWidgetEntryView: View { var entry: Provider.Entry @Environment(\.widgetFamily) var family diff --git a/DesktopWidgetTool/LaunchPadWidget/MediumLaunchPadWidgetView.swift b/DesktopWidgetTool/LaunchPadWidget/MediumLaunchPadWidgetView.swift index a05cfec..f7883c2 100644 --- a/DesktopWidgetTool/LaunchPadWidget/MediumLaunchPadWidgetView.swift +++ b/DesktopWidgetTool/LaunchPadWidget/MediumLaunchPadWidgetView.swift @@ -9,25 +9,25 @@ import SwiftUI struct MediumLaunchPadWidgetView: View { let repos: [LaunchpadRepo] - + var body: some View { ViewThatFits { WrappingHStack { WidgetLaunchPadRow(repos: repos, length: 10) } - + WrappingHStack { WidgetLaunchPadRow(repos: repos, length: 9) } - + WrappingHStack { WidgetLaunchPadRow(repos: repos, length: 8) } - + WrappingHStack { WidgetLaunchPadRow(repos: repos, length: 7) } - + WrappingHStack { WidgetLaunchPadRow(repos: repos, length: 6) } diff --git a/DesktopWidgetTool/MergeRequestWiget/ExtraLargeMergeRequestWidgetInterface.swift b/DesktopWidgetTool/MergeRequestWiget/ExtraLargeMergeRequestWidgetInterface.swift index f3ee746..6573f85 100644 --- a/DesktopWidgetTool/MergeRequestWiget/ExtraLargeMergeRequestWidgetInterface.swift +++ b/DesktopWidgetTool/MergeRequestWiget/ExtraLargeMergeRequestWidgetInterface.swift @@ -81,7 +81,6 @@ struct ExtraLargeMergeRequestWidgetInterface: View { } } - #Preview { ExtraLargeMergeRequestWidgetInterface( mergeRequests: [.preview, .preview, .preview, .preview], diff --git a/DesktopWidgetTool/MergeRequestWiget/LargeMergeRequestWidgetInterface.swift b/DesktopWidgetTool/MergeRequestWiget/LargeMergeRequestWidgetInterface.swift index db986d6..d54f1e9 100644 --- a/DesktopWidgetTool/MergeRequestWiget/LargeMergeRequestWidgetInterface.swift +++ b/DesktopWidgetTool/MergeRequestWiget/LargeMergeRequestWidgetInterface.swift @@ -63,8 +63,6 @@ struct LargeMergeRequestWidgetInterface: View { } } - - #Preview { LargeMergeRequestWidgetInterface( mergeRequests: [.preview, .preview, .preview, .preview], diff --git a/DesktopWidgetTool/MergeRequestWiget/MediumMergeRequestWidgetInterface.swift b/DesktopWidgetTool/MergeRequestWiget/MediumMergeRequestWidgetInterface.swift index e968923..9a4b592 100644 --- a/DesktopWidgetTool/MergeRequestWiget/MediumMergeRequestWidgetInterface.swift +++ b/DesktopWidgetTool/MergeRequestWiget/MediumMergeRequestWidgetInterface.swift @@ -35,7 +35,7 @@ struct MediumMergeRequestWidgetInterface: View { Text(Image(.mergeRequest)) Text("^[\(mergeRequests.count) reviews](inflect: true) requested") } - + HStack(alignment: .center, spacing: 6) { Text(Image(.mergeRequest)) Text(mergeRequests.count.description) @@ -58,8 +58,8 @@ struct MediumMergeRequestWidgetInterface: View { } VStack(alignment: .leading, spacing: 4) { - ForEach(Array(mergeRequests.prefix(5)), id: \.id) { MR in - WidgetMRRowIcon(MR: MR, providers: providers) + ForEach(Array(mergeRequests.prefix(5)), id: \.id) { request in + WidgetMRRowIcon(request: request, providers: providers) } } } @@ -67,7 +67,6 @@ struct MediumMergeRequestWidgetInterface: View { } } - #Preview { VStack { GroupBox { @@ -93,8 +92,6 @@ struct MediumMergeRequestWidgetInterface: View { .scenePadding() } - - #Preview { MediumMergeRequestWidgetInterface( mergeRequests: [.preview, .preview, .preview, .preview], @@ -103,4 +100,3 @@ struct MediumMergeRequestWidgetInterface: View { selectedView: .authoredMergeRequests ) } - diff --git a/DesktopWidgetTool/MergeRequestWiget/MergeRequestWidgetEntryView.swift b/DesktopWidgetTool/MergeRequestWiget/MergeRequestWidgetEntryView.swift index 8dee83c..2072731 100644 --- a/DesktopWidgetTool/MergeRequestWiget/MergeRequestWidgetEntryView.swift +++ b/DesktopWidgetTool/MergeRequestWiget/MergeRequestWidgetEntryView.swift @@ -8,7 +8,7 @@ import SwiftUI import WidgetKit -struct MergeRequestWidgetEntryView : View { +struct MergeRequestWidgetEntryView: View { var entry: Provider.Entry @Environment(\.widgetFamily) private var family diff --git a/DesktopWidgetTool/WidgetLaunchPadRow.swift b/DesktopWidgetTool/WidgetLaunchPadRow.swift index 300456e..51f123e 100644 --- a/DesktopWidgetTool/WidgetLaunchPadRow.swift +++ b/DesktopWidgetTool/WidgetLaunchPadRow.swift @@ -11,7 +11,7 @@ struct WidgetLaunchPadRow: View { let repos: [LaunchpadRepo] let length: Int var body: some View { - HStack() { + HStack { ForEach(repos.prefix(length), id: \.id) { repo in LaunchpadItem(repo: repo) } diff --git a/GitLab.xcodeproj/project.pbxproj b/GitLab.xcodeproj/project.pbxproj index b91414c..a6caae0 100644 --- a/GitLab.xcodeproj/project.pbxproj +++ b/GitLab.xcodeproj/project.pbxproj @@ -88,7 +88,7 @@ 8A7935C22A5583E400F8FB6C /* LaunchpadState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE12A55817400819B80 /* LaunchpadState.swift */; }; 8A7935C62A5583E400F8FB6C /* NotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE52A55817400819B80 /* NotificationManager.swift */; }; 8A7935C72A5583E400F8FB6C /* NetworkManagerGitLab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE62A55817400819B80 /* NetworkManagerGitLab.swift */; }; - 8A7935C82A5583E400F8FB6C /* GitLabISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE82A55817400819B80 /* GitLabISO8601DateFormatter.swift */; }; + 8A7935C82A5583E400F8FB6C /* gitlabISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE82A55817400819B80 /* gitlabISO8601DateFormatter.swift */; }; 8A7935C92A5583E400F8FB6C /* CachedAsyncImage+ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE92A55817400819B80 /* CachedAsyncImage+ImageCache.swift */; }; 8A7935CF2A5583E400F8FB6C /* NetworkReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CEF2A55817400819B80 /* NetworkReachability.swift */; }; 8A7935D02A5583E400F8FB6C /* NoticeMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CF12A55817400819B80 /* NoticeMessage.swift */; }; @@ -169,6 +169,7 @@ 8A7C0AFE2CD3657100E479CA /* UniversalMergeRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A7C0AFC2CD3657100E479CA /* UniversalMergeRequest.swift */; }; 8A7C0AFF2CD3657100E479CA /* UniversalMergeRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A7C0AFC2CD3657100E479CA /* UniversalMergeRequest.swift */; }; 8A7C0B002CD3657100E479CA /* UniversalMergeRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A7C0AFC2CD3657100E479CA /* UniversalMergeRequest.swift */; }; + 8A858F142CD4F25E0024795D /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = 8A858F132CD4F25B0024795D /* .swiftlint.yml */; }; 8A91E2172CB7B68900BE51B9 /* UserAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A91E2162CB7B68900BE51B9 /* UserAvatarView.swift */; }; 8A91E2182CB7B68900BE51B9 /* UserAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A91E2162CB7B68900BE51B9 /* UserAvatarView.swift */; }; 8A91E2192CB7B68900BE51B9 /* UserAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A91E2162CB7B68900BE51B9 /* UserAvatarView.swift */; }; @@ -269,7 +270,7 @@ 8AE8A7072B989EFA002B3C9E /* CIPendingIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CFF2A55817400819B80 /* CIPendingIcon.swift */; }; 8AE8A7082B989EFA002B3C9E /* MenuBarButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80D1F2A55817400819B80 /* MenuBarButtonStyle.swift */; }; 8AE8A7092B989EFA002B3C9E /* CISkippedIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CF52A55817400819B80 /* CISkippedIcon.swift */; }; - 8AE8A70A2B989EFA002B3C9E /* GitLabISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE82A55817400819B80 /* GitLabISO8601DateFormatter.swift */; }; + 8AE8A70A2B989EFA002B3C9E /* gitlabISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE82A55817400819B80 /* gitlabISO8601DateFormatter.swift */; }; 8AE8A70B2B989EFA002B3C9E /* NoticeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CF32A55817400819B80 /* NoticeState.swift */; }; 8AE8A70D2B989EFA002B3C9E /* CachedAsyncImage+ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE92A55817400819B80 /* CachedAsyncImage+ImageCache.swift */; }; 8AE8A70E2B989EFA002B3C9E /* NotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE52A55817400819B80 /* NotificationManager.swift */; }; @@ -330,8 +331,8 @@ 8AF80D342A55817400819B80 /* NetworkManagerGitLab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE62A55817400819B80 /* NetworkManagerGitLab.swift */; }; 8AF80D362A55817400819B80 /* StructsGitLab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE72A55817400819B80 /* StructsGitLab.swift */; }; 8AF80D372A55817400819B80 /* StructsGitLab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE72A55817400819B80 /* StructsGitLab.swift */; }; - 8AF80D392A55817400819B80 /* GitLabISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE82A55817400819B80 /* GitLabISO8601DateFormatter.swift */; }; - 8AF80D3A2A55817400819B80 /* GitLabISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE82A55817400819B80 /* GitLabISO8601DateFormatter.swift */; }; + 8AF80D392A55817400819B80 /* gitlabISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE82A55817400819B80 /* gitlabISO8601DateFormatter.swift */; }; + 8AF80D3A2A55817400819B80 /* gitlabISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE82A55817400819B80 /* gitlabISO8601DateFormatter.swift */; }; 8AF80D3C2A55817400819B80 /* CachedAsyncImage+ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE92A55817400819B80 /* CachedAsyncImage+ImageCache.swift */; }; 8AF80D3D2A55817400819B80 /* CachedAsyncImage+ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CE92A55817400819B80 /* CachedAsyncImage+ImageCache.swift */; }; 8AF80D4E2A55817400819B80 /* NetworkReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF80CEF2A55817400819B80 /* NetworkReachability.swift */; }; @@ -581,6 +582,7 @@ 8A7C0AF22CD3650000E479CA /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = ""; }; 8A7C0AFC2CD3657100E479CA /* UniversalMergeRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UniversalMergeRequest.swift; sourceTree = ""; }; 8A7FBF6729C3326D0032E394 /* GitLabAPIService.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; path = GitLabAPIService.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; + 8A858F132CD4F25B0024795D /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; 8A91E2142CB7B5FE00BE51B9 /* en.xcloc */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = en.xcloc; sourceTree = ""; }; 8A91E2162CB7B68900BE51B9 /* UserAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAvatarView.swift; sourceTree = ""; }; 8A9D87892BD2736C00E2C0CD /* ProjectLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectLink.swift; sourceTree = ""; }; @@ -626,7 +628,7 @@ 8AF80CE52A55817400819B80 /* NotificationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = ""; }; 8AF80CE62A55817400819B80 /* NetworkManagerGitLab.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkManagerGitLab.swift; sourceTree = ""; }; 8AF80CE72A55817400819B80 /* StructsGitLab.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StructsGitLab.swift; sourceTree = ""; }; - 8AF80CE82A55817400819B80 /* GitLabISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GitLabISO8601DateFormatter.swift; sourceTree = ""; }; + 8AF80CE82A55817400819B80 /* gitlabISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = gitlabISO8601DateFormatter.swift; sourceTree = ""; }; 8AF80CE92A55817400819B80 /* CachedAsyncImage+ImageCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CachedAsyncImage+ImageCache.swift"; sourceTree = ""; }; 8AF80CEF2A55817400819B80 /* NetworkReachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkReachability.swift; sourceTree = ""; }; 8AF80CF12A55817400819B80 /* NoticeMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoticeMessage.swift; sourceTree = ""; }; @@ -840,6 +842,7 @@ 8A5FC0ED26EFD08E004136AB = { isa = PBXGroup; children = ( + 8A858F132CD4F25B0024795D /* .swiftlint.yml */, 8A91E2152CB7B5FE00BE51B9 /* GitLab Localizations */, 8A13B85D2A66A3E30090A6D9 /* Credits.rtf */, 8AF80BE92A5580E700819B80 /* Shared */, @@ -1019,7 +1022,7 @@ children = ( 8AC0C2092A5D3D720096772B /* AccessToken.swift */, 8AF80CE92A55817400819B80 /* CachedAsyncImage+ImageCache.swift */, - 8AF80CE82A55817400819B80 /* GitLabISO8601DateFormatter.swift */, + 8AF80CE82A55817400819B80 /* gitlabISO8601DateFormatter.swift */, 8A111F4D2CC1387F00DEB0DD /* NetworkEvent.swift */, 8A111F522CC1388900DEB0DD /* NetworkInfo.swift */, 8AF80CE62A55817400819B80 /* NetworkManagerGitLab.swift */, @@ -1255,6 +1258,7 @@ buildRules = ( ); dependencies = ( + 8AD9D9E92CD4F0B600BE229B /* PBXTargetDependency */, 8A36AF1C2869B4110008B949 /* PBXTargetDependency */, 8AE8A6F52B989E9B002B3C9E /* PBXTargetDependency */, ); @@ -1376,6 +1380,7 @@ packageReferences = ( 8AF80DD52A5581A600819B80 /* XCRemoteSwiftPackageReference "Get" */, 8AF80DD82A5581B700819B80 /* XCRemoteSwiftPackageReference "CachedAsyncImage" */, + 8AD9D9E72CD4F05600BE229B /* XCRemoteSwiftPackageReference "SwiftLintPlugins" */, ); productRefGroup = 8A5FC0F726EFD08E004136AB /* Products */; projectDirPath = ""; @@ -1430,6 +1435,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8A858F142CD4F25E0024795D /* .swiftlint.yml in Resources */, 8A5B657528E4E76000535C61 /* Assets.xcassets in Resources */, 8A13B85E2A66A3E30090A6D9 /* Credits.rtf in Resources */, 8A5FC10126EFD08F004136AB /* Preview Assets.xcassets in Resources */, @@ -1505,7 +1511,7 @@ 8A7C0ACE2CCFEBD100E479CA /* DateCompare.swift in Sources */, 8AF80D222A55817400819B80 /* NetworkManagerGitLab+repoLaunchPad.swift in Sources */, 8AF80D342A55817400819B80 /* NetworkManagerGitLab.swift in Sources */, - 8AF80D3A2A55817400819B80 /* GitLabISO8601DateFormatter.swift in Sources */, + 8AF80D3A2A55817400819B80 /* gitlabISO8601DateFormatter.swift in Sources */, 8AF80D312A55817400819B80 /* NotificationManager.swift in Sources */, 8AE274212CC3D3A90059244E /* WidgetMRRowIcon.swift in Sources */, 8AFAE1932BEB7C1C0030541E /* MergeRequestList.swift in Sources */, @@ -1596,7 +1602,7 @@ 8A7935C62A5583E400F8FB6C /* NotificationManager.swift in Sources */, 8ACBFD3E2CC280F300A8753B /* WidgetApprovedReviewIcon.swift in Sources */, 8A7935C72A5583E400F8FB6C /* NetworkManagerGitLab.swift in Sources */, - 8A7935C82A5583E400F8FB6C /* GitLabISO8601DateFormatter.swift in Sources */, + 8A7935C82A5583E400F8FB6C /* gitlabISO8601DateFormatter.swift in Sources */, 8AC0C2102A5D51FA0096772B /* TokenInformationView.swift in Sources */, 8ABBD2082B7E2E70007C03E6 /* Array+Difference.swift in Sources */, 8A111F562CC1388900DEB0DD /* NetworkInfo.swift in Sources */, @@ -1723,7 +1729,7 @@ 8AF80D3C2A55817400819B80 /* CachedAsyncImage+ImageCache.swift in Sources */, 8AC7B4B92CB5BFD400CBD21C /* CIWarningIcon.swift in Sources */, 8AF80DAE2A55817400819B80 /* MergeStatusView.swift in Sources */, - 8AF80D392A55817400819B80 /* GitLabISO8601DateFormatter.swift in Sources */, + 8AF80D392A55817400819B80 /* gitlabISO8601DateFormatter.swift in Sources */, 8ACBFD3C2CC270AC00A8753B /* PluralWidgetTitle.swift in Sources */, 8AF80D782A55817400819B80 /* CIPendingIcon.swift in Sources */, 8A111F272CC116DE00DEB0DD /* MRTitleView.swift in Sources */, @@ -1836,7 +1842,7 @@ 8AB969222BDBC2170078E5CD /* LaunchPadWidgetEntryView.swift in Sources */, 8AE8A7082B989EFA002B3C9E /* MenuBarButtonStyle.swift in Sources */, 8AE8A7092B989EFA002B3C9E /* CISkippedIcon.swift in Sources */, - 8AE8A70A2B989EFA002B3C9E /* GitLabISO8601DateFormatter.swift in Sources */, + 8AE8A70A2B989EFA002B3C9E /* gitlabISO8601DateFormatter.swift in Sources */, 8AE8A70B2B989EFA002B3C9E /* NoticeState.swift in Sources */, 8A111F472CC1384E00DEB0DD /* NetworkStateView.swift in Sources */, 8AE274202CC3D3A90059244E /* WidgetMRRowIcon.swift in Sources */, @@ -1957,6 +1963,10 @@ target = 8A5FC0F526EFD08E004136AB /* GitLab */; targetProxy = 8A5FC11726EFD08F004136AB /* PBXContainerItemProxy */; }; + 8AD9D9E92CD4F0B600BE229B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + productRef = 8AD9D9E82CD4F0B600BE229B /* SwiftLintBuildToolPlugin */; + }; 8AE8A6F52B989E9B002B3C9E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 8AE8A6E72B989E9A002B3C9E /* DesktopWidgetToolExtension */; @@ -2658,6 +2668,14 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + 8AD9D9E72CD4F05600BE229B /* XCRemoteSwiftPackageReference "SwiftLintPlugins" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SimplyDanny/SwiftLintPlugins"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.57.0; + }; + }; 8AF80DD52A5581A600819B80 /* XCRemoteSwiftPackageReference "Get" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/kean/Get.git"; @@ -2687,6 +2705,11 @@ package = 8AF80DD82A5581B700819B80 /* XCRemoteSwiftPackageReference "CachedAsyncImage" */; productName = CachedAsyncImage; }; + 8AD9D9E82CD4F0B600BE229B /* SwiftLintBuildToolPlugin */ = { + isa = XCSwiftPackageProductDependency; + package = 8AD9D9E72CD4F05600BE229B /* XCRemoteSwiftPackageReference "SwiftLintPlugins" */; + productName = "plugin:SwiftLintBuildToolPlugin"; + }; 8AE024DA2A92457C000548D7 /* Get */ = { isa = XCSwiftPackageProductDependency; package = 8AF80DD52A5581A600819B80 /* XCRemoteSwiftPackageReference "Get" */; diff --git a/GitLab.xcworkspace/xcshareddata/swiftpm/Package.resolved b/GitLab.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3f28bc3..0c1c232 100644 --- a/GitLab.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/GitLab.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "2a06bdaff6864ba8fd3d180b93a1d7654ccffbbd662bf8961c590b0a27d94d84", + "originHash" : "75bcd917641bb1362fd62b8cc32a042de0afd97dd45ce311986971069dbd5920", "pins" : [ { "identity" : "cachedasyncimage", @@ -18,6 +18,15 @@ "revision" : "12830cc64f31789ae6f4352d2d51d03a25fc3741", "version" : "2.1.6" } + }, + { + "identity" : "swiftlintplugins", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SimplyDanny/SwiftLintPlugins", + "state" : { + "revision" : "7c80ce6f142164b0201871e580b021d1b2c69804", + "version" : "0.57.0" + } } ], "version" : 3 diff --git a/GitLab/ExtraWindow.swift b/GitLab/ExtraWindow.swift index 76158d3..88c4c74 100644 --- a/GitLab/ExtraWindow.swift +++ b/GitLab/ExtraWindow.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 31/10/2024. // - import SwiftUI import SwiftData @@ -53,7 +52,7 @@ struct ExtraWindow: View { openURL(url) } .toolbar { - ToolbarItem() { + ToolbarItem { Picker(selection: $selectedView, content: { Text("Merge Requests").tag(QueryType.authoredMergeRequests) Text("Review requested").tag(QueryType.reviewRequestedMergeRequests) diff --git a/GitLab/GitLabApp.swift b/GitLab/GitLabApp.swift index 51146fd..1709335 100644 --- a/GitLab/GitLabApp.swift +++ b/GitLab/GitLabApp.swift @@ -14,7 +14,7 @@ struct GitLabApp: App { @Environment(\.openURL) var openURL - @State var receivedURL: URL? = nil + @State var receivedURL: URL? @Environment(\.openWindow) private var openWindow @Environment(\.dismissWindow) private var dismissWindow @@ -50,7 +50,6 @@ struct GitLabApp: App { .menuBarExtraStyle(.window) .windowResizability(.contentSize) - Settings { SettingsView() .modelContainer(sharedModelContainer) diff --git a/GitLab/PopoverResize.swift b/GitLab/PopoverResize.swift index cb9e75e..0ac93ed 100644 --- a/GitLab/PopoverResize.swift +++ b/GitLab/PopoverResize.swift @@ -33,7 +33,7 @@ public class PopoverResize: NSPopover { private var trackLeftBottom: NSView.TrackingRectTag? private var trackRightBottom: NSView.TrackingRectTag? private var trackBottom: NSView.TrackingRectTag? - private var sizeChanged: ((_ size: NSSize) -> Void)? = nil + private var sizeChanged: ((_ size: NSSize) -> Void)? private let cursorLeftRight = PopoverResize.getCursor("resizeeastwest") private let cursorLeftBottom = PopoverResize.getCursor("resizenortheastsouthwest") @@ -184,7 +184,7 @@ public class PopoverResize: NSPopover { } } - private func setCursor(){ + private func setCursor() { switch region { case .Left: fallthrough case .Right: diff --git a/GitLabAPIService/GitLabAPIService/GitLabAPIService.swift b/GitLabAPIService/GitLabAPIService/GitLabAPIService.swift index b271792..8534030 100644 --- a/GitLabAPIService/GitLabAPIService/GitLabAPIService.swift +++ b/GitLabAPIService/GitLabAPIService/GitLabAPIService.swift @@ -9,7 +9,7 @@ import Foundation /// This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection. class GitLabAPIService: NSObject, GitLabAPIServiceProtocol { - + /// This implements the example protocol. Replace the body of this class with the implementation of this service's protocol. @objc func uppercase(string: String, with reply: @escaping (String) -> Void) { let response = string.uppercased() diff --git a/GitLabAPIService/GitLabAPIService/GitLabAPIServiceProtocol.swift b/GitLabAPIService/GitLabAPIService/GitLabAPIServiceProtocol.swift index 4941ebe..a42d715 100644 --- a/GitLabAPIService/GitLabAPIService/GitLabAPIServiceProtocol.swift +++ b/GitLabAPIService/GitLabAPIService/GitLabAPIServiceProtocol.swift @@ -9,7 +9,7 @@ import Foundation /// The protocol that this service will vend as its API. This protocol will also need to be visible to the process hosting the service. @objc public protocol GitLabAPIServiceProtocol { - + /// Replace the API of this protocol with an API appropriate to the service you are vending. func uppercase(string: String, with reply: @escaping (String) -> Void) } diff --git a/GitLabAPIService/GitLabAPIService/main.swift b/GitLabAPIService/GitLabAPIService/main.swift index acb65fb..232c1b7 100644 --- a/GitLabAPIService/GitLabAPIService/main.swift +++ b/GitLabAPIService/GitLabAPIService/main.swift @@ -8,21 +8,21 @@ import Foundation class ServiceDelegate: NSObject, NSXPCListenerDelegate { - + /// This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection. func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { - + // Configure the connection. // First, set the interface that the exported object implements. newConnection.exportedInterface = NSXPCInterface(with: GitLabAPIServiceProtocol.self) - + // Next, set the object that the connection exports. All messages sent on the connection to this service will be sent to the exported object to handle. The connection retains the exported object. let exportedObject = GitLabAPIService() newConnection.exportedObject = exportedObject - + // Resuming the connection allows the system to deliver more incoming messages. newConnection.resume() - + // Returning true from this method tells the system that you have accepted this connection. If you want to reject the connection for some reason, call invalidate() on the connection and return false. return true } diff --git a/GitLabTests/GitLabTests.swift b/GitLabTests/GitLabTests.swift index 7729904..4391db2 100644 --- a/GitLabTests/GitLabTests.swift +++ b/GitLabTests/GitLabTests.swift @@ -36,7 +36,6 @@ class GitLabTests: XCTestCase { // Use XCTAssert and related functions to verify your tests produce the correct results. } - func testGitLabDateParsingBulk() throws { let inputs = [ "2023-10-30T10:40:00+01:00", diff --git a/NotificationContent/NotificationViewController.swift b/NotificationContent/NotificationViewController.swift index b3419eb..e83d132 100644 --- a/NotificationContent/NotificationViewController.swift +++ b/NotificationContent/NotificationViewController.swift @@ -17,10 +17,6 @@ class NotificationViewController: NSHostingController, U super.init(coder: coder, rootView: CIJobsNotificationView(stages: [])) } - override func viewDidLoad() { - super.viewDidLoad() - } - func didReceive(_ notification: UNNotification) { if let jsonData = notification.request.content.userInfo["PIPELINE_STATUS"] as? Data, let headPipeline = try? JSONDecoder().decode(GitLab.HeadPipeline.self, from: jsonData) { diff --git a/Shared/UserInterface/ButtonStyles/ShadedButton.swift b/Shared/UserInterface/ButtonStyles/ShadedButton.swift index 46a488c..3760162 100644 --- a/Shared/UserInterface/ButtonStyles/ShadedButton.swift +++ b/Shared/UserInterface/ButtonStyles/ShadedButton.swift @@ -7,7 +7,6 @@ import SwiftUI - struct ShadedButtonStyle: ButtonStyle { @State private var isHovering = false diff --git a/Shared/UserInterface/EnvironmentValues/IsInWidget.swift b/Shared/UserInterface/EnvironmentValues/IsInWidget.swift index 7031026..916fde2 100644 --- a/Shared/UserInterface/EnvironmentValues/IsInWidget.swift +++ b/Shared/UserInterface/EnvironmentValues/IsInWidget.swift @@ -7,7 +7,6 @@ import SwiftUI - private struct IsInWidgetKey: EnvironmentKey { static let defaultValue = false } diff --git a/Shared/UserInterface/Extensions/Collection.swift b/Shared/UserInterface/Extensions/Collection.swift index 881f465..d312ec9 100644 --- a/Shared/UserInterface/Extensions/Collection.swift +++ b/Shared/UserInterface/Extensions/Collection.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 31/10/2024. // - extension BidirectionalCollection where Element == CollectionDifference.Change { /// Return all elements of changed type `.insert` var insertedElements: [GitLab.Author] { @@ -16,7 +15,7 @@ extension BidirectionalCollection where Element == CollectionDifference GitLab.Author? in @@ -45,7 +44,7 @@ extension Sequence { extension Sequence where Element: Hashable { func uniqueElements() -> [Element] { - return uniqueElements(byProperty: { $0 }) + return uniqueElements(byProperty: { $0 }) } } diff --git a/Shared/UserInterface/Extensions/DateCompare.swift b/Shared/UserInterface/Extensions/DateCompare.swift index babbd8a..70880d3 100644 --- a/Shared/UserInterface/Extensions/DateCompare.swift +++ b/Shared/UserInterface/Extensions/DateCompare.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 28/10/2024. // - import Foundation extension Date { diff --git a/Shared/UserInterface/Extensions/IfViewModifier.swift b/Shared/UserInterface/Extensions/IfViewModifier.swift index f76c1e1..6dd3065 100644 --- a/Shared/UserInterface/Extensions/IfViewModifier.swift +++ b/Shared/UserInterface/Extensions/IfViewModifier.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 21/10/2024. // - import SwiftUI extension View { diff --git a/Shared/UserInterface/Extensions/TranslucentWindowStyle.swift b/Shared/UserInterface/Extensions/TranslucentWindowStyle.swift index 70815ba..44f5778 100644 --- a/Shared/UserInterface/Extensions/TranslucentWindowStyle.swift +++ b/Shared/UserInterface/Extensions/TranslucentWindowStyle.swift @@ -1,14 +1,13 @@ import SwiftUI - public protocol WindowBackgroundStyle { - associatedtype Body : View + associatedtype Body: View @ViewBuilder @MainActor var backgroud: Self.Body { get } } extension WindowBackgroundStyle where Self == TranslucentBackgroundStyle { public static var translucent: TranslucentBackgroundStyle { TranslucentBackgroundStyle(config: .translucent) } - + public static func hiddenTitleBar(material: NSVisualEffectView.Material) -> TranslucentBackgroundStyle { TranslucentBackgroundStyle(config: .translucent(material: material)) } @@ -22,27 +21,33 @@ public struct TranslucentBackgroundStyle: WindowBackgroundStyle { } extension View { - - @MainActor public func presentedWindowBackgroundStyle(_ style: S) -> some View where S : WindowBackgroundStyle { + + @MainActor public func presentedWindowBackgroundStyle(_ style: S) -> some View where S: WindowBackgroundStyle { self.background(style.backgroud) } } struct TranslucentWindowBackground: NSViewRepresentable { - + let config: WindowConfiguration - + enum ContentViewConfiguration { case embed(NSView?) case replace(NSView?) } - + enum StyleMaskConfiguration { case insert(NSWindow.StyleMask) case replace(NSWindow.StyleMask) } - + + public struct StandardWindowButtonConfiguration { + let miniaturizeButtonIsHidden: Bool + let closeButtonIsHidden: Bool + let zoomButtonIsHidden: Bool + } + struct WindowConfiguration { let isOpaque: Bool let backgroundColor: NSColor @@ -52,13 +57,7 @@ struct TranslucentWindowBackground: NSViewRepresentable { let titleVisibility: NSWindow.TitleVisibility let standardWindowButtonConfig: StandardWindowButtonConfiguration let isMovableByWindowBackground: Bool - - public struct StandardWindowButtonConfiguration { - let miniaturizeButtonIsHidden: Bool - let closeButtonIsHidden: Bool - let zoomButtonIsHidden: Bool - } - + static func getTranlucentBackground(material: NSVisualEffectView.Material) -> NSView { let visualEffect = NSVisualEffectView() visualEffect.blendingMode = .behindWindow @@ -66,7 +65,7 @@ struct TranslucentWindowBackground: NSViewRepresentable { visualEffect.material = material return visualEffect } - + static let translucent: WindowConfiguration = WindowConfiguration( isOpaque: false, backgroundColor: NSColor.clear, @@ -81,7 +80,7 @@ struct TranslucentWindowBackground: NSViewRepresentable { ), isMovableByWindowBackground: true ) - + static func translucent(material: NSVisualEffectView.Material) -> WindowConfiguration { WindowConfiguration( isOpaque: false, @@ -98,12 +97,12 @@ struct TranslucentWindowBackground: NSViewRepresentable { isMovableByWindowBackground: true ) } - + static func configure(window: NSWindow, forConfig config: WindowConfiguration) { - + window.isOpaque = config.isOpaque window.backgroundColor = config.backgroundColor - + switch config.contentViewCofiguration { case let .replace(view): window.contentView = view @@ -114,14 +113,14 @@ struct TranslucentWindowBackground: NSViewRepresentable { view?.addSubview(currentContentView) } } - + switch config.styleMaskConfiguration { case let .replace(mask): window.styleMask = mask case let .insert(mask): window.styleMask.insert(mask) } - + window.titlebarAppearsTransparent = config.titlebarAppearsTransparent window.titleVisibility = config.titleVisibility window.titlebarSeparatorStyle = .line @@ -131,22 +130,20 @@ struct TranslucentWindowBackground: NSViewRepresentable { window.isMovableByWindowBackground = config.isMovableByWindowBackground } } - - + func makeCoordinator() -> Coordinator { Coordinator(config: config) } - - + class Coordinator: NSObject { - + let config: WindowConfiguration private var _originalWindowConfiguration: WindowConfiguration? - + init(config: WindowConfiguration) { self.config = config } - + func createWindowConfigurationForCurrentContext(_ context: NSWindow) -> WindowConfiguration { WindowConfiguration( isOpaque: context.isOpaque, @@ -155,7 +152,7 @@ struct TranslucentWindowBackground: NSViewRepresentable { styleMaskConfiguration: .replace(context.styleMask), titlebarAppearsTransparent: context.titlebarAppearsTransparent, titleVisibility: context.titleVisibility, - standardWindowButtonConfig: WindowConfiguration.StandardWindowButtonConfiguration( + standardWindowButtonConfig: StandardWindowButtonConfiguration( miniaturizeButtonIsHidden: context.standardWindowButton(.miniaturizeButton)?.isHidden ?? false, closeButtonIsHidden: context.standardWindowButton(.closeButton)?.isHidden ?? false, zoomButtonIsHidden: context.standardWindowButton(.zoomButton)?.isHidden ?? false @@ -163,21 +160,21 @@ struct TranslucentWindowBackground: NSViewRepresentable { isMovableByWindowBackground: context.isMovableByWindowBackground ) } - + func makeWindowTranslucent(window: NSWindow?) { guard let window = window else { return } self._originalWindowConfiguration = createWindowConfigurationForCurrentContext(window) let translucentWindowConfiguration = config WindowConfiguration.configure(window: window, forConfig: translucentWindowConfiguration) } - + func resetWindow(window: NSWindow) { if let originalWindowConfiguration = _originalWindowConfiguration { WindowConfiguration.configure(window: window, forConfig: originalWindowConfiguration) } } } - + func makeNSView(context: Context) -> NSView { let view = NSView() DispatchQueue.main.async { @@ -186,11 +183,11 @@ struct TranslucentWindowBackground: NSViewRepresentable { } return view } - + func updateNSView(_ nsView: NSView, context: Context) { - + } - + static func dismantleNSView(_ nsView: NSView, coordinator: Coordinator) { guard let window = nsView.window else { return @@ -198,5 +195,3 @@ struct TranslucentWindowBackground: NSViewRepresentable { coordinator.resetWindow(window: window) } } - - diff --git a/Shared/UserInterface/Icons/ApprovedReviewIcon.swift b/Shared/UserInterface/Icons/ApprovedReviewIcon.swift index 6d4eb00..566d608 100644 --- a/Shared/UserInterface/Icons/ApprovedReviewIcon.swift +++ b/Shared/UserInterface/Icons/ApprovedReviewIcon.swift @@ -17,32 +17,31 @@ struct ApprovedReviewIcon: View { @Environment(\.colorScheme) private var colorScheme var approvedBy: [Approval] var account: Account? - + private var instance: String { account?.instance ?? "https://gitlab.com" } - + // @State private var isHovering: Bool = false - + private var names: String { approvedBy.map { author in return author.name ?? author.username ?? "" }.filter({ !$0.isEmpty}).formatted() } - + var largeView: some View { - HStack() { + HStack { Image(systemName: "checkmark") .font(.system(size: 9, weight: .semibold)) .help(String(localized: "Merge request approved")) // .clipShape(Rectangle()) .padding(.vertical, 2) - - + HStack { Text("Approved") .fixedSize() - + AvatarRowView(approvedBy: approvedBy, account: account) } .font(.system(size: 11, weight: .regular)) @@ -54,7 +53,7 @@ struct ApprovedReviewIcon: View { ) .animation(.snappy) ) - + } .foregroundStyle(.green.mix(with: .black, by: colorScheme == .dark ? 0 : 0.2)) .padding(.leading, 6) @@ -72,10 +71,10 @@ struct ApprovedReviewIcon: View { // }) .help(String(localized: "Approved by \(names)")) } - + /// TODO: Diff in style from CI completed check circle var smallView: some View { - HStack() { + HStack { Image(systemName: "checkmark") .font(.system(size: 9, weight: .semibold)) .help(String(localized: "Merge request approved")) @@ -91,12 +90,12 @@ struct ApprovedReviewIcon: View { ) .animation(.smooth, value: approvedBy) } - + var body: some View { VStack(alignment: .trailing) { ViewThatFits(in: .horizontal, content: { largeView - + smallView }) } @@ -107,31 +106,31 @@ struct ApprovedReviewIcon: View { #Preview("Change authors") { @Previewable @State var authors: [Approval] = [.preview] VStack { - + ApprovedReviewIcon(approvedBy: authors, account: .preview) .scenePadding() - + HStack { - + Button("+") { let author: Approval? = [.preview, .preview2, .preview3, .preview4].randomElement() if let author { authors.append(author) } } - + Button("reset") { let author: Approval? = [.preview, .preview2, .preview3, .preview4].randomElement() if let author { authors = [author] } } - + Button("-") { _ = authors.popLast() } } - + }.scenePadding() } @@ -140,19 +139,16 @@ struct ApprovedReviewIcon: View { VStack { HStack { Text("MR Title") - + Spacer() - + if show { ApprovedReviewIcon(approvedBy: [.preview2, .preview3], account: .preview) } } .frame(maxWidth: .infinity, alignment: .leading) .scenePadding() - - - - + Button("toggle") { withAnimation { show.toggle() @@ -167,29 +163,28 @@ struct ApprovedReviewIcon: View { .scenePadding() ApprovedReviewIcon(approvedBy: [.preview2, .preview3], account: .preview) .scenePadding() - + ApprovedReviewIcon(approvedBy: [.preview2, .preview3, .preview2], account: .preview) .scenePadding() - + ApprovedReviewIcon(approvedBy: [.preview2, .preview3, .preview2, .preview3], account: .preview) .scenePadding() - - + ApprovedReviewIcon(approvedBy: [.preview, .preview2, .preview3, .preview2, .preview3, .preview, .preview2, .preview3, .preview2, .preview3], account: .preview) .scenePadding() - + ApprovedReviewIcon(approvedBy: [.preview, .preview2, .preview3], account: .preview) .scenePadding() - + ApprovedReviewIcon(approvedBy: [.preview], account: .preview) .scenePadding() - + GroupBox("Small", content: { ApprovedReviewIcon(approvedBy: [.preview, .preview2, .preview3, .preview2, .preview3, .preview, .preview2, .preview3, .preview2, .preview3], account: .preview) .scenePadding() }) .frame(maxWidth: 100) - + GroupBox("Large", content: { ApprovedReviewIcon(approvedBy: [.preview, .preview2, .preview3, .preview2, .preview3, .preview, .preview2, .preview3, .preview2, .preview3], account: .preview) .scenePadding() diff --git a/Shared/UserInterface/Icons/DiscussionCountIcon.swift b/Shared/UserInterface/Icons/DiscussionCountIcon.swift index a7a5ff0..0910ce1 100644 --- a/Shared/UserInterface/Icons/DiscussionCountIcon.swift +++ b/Shared/UserInterface/Icons/DiscussionCountIcon.swift @@ -8,7 +8,7 @@ import SwiftUI struct DiscussionCountIcon: View { - var count: Int? = nil + var count: Int? var body: some View { if let count = count, count > 1 { if count <= 50 { diff --git a/Shared/UserInterface/Icons/NeedsReviewIcon.swift b/Shared/UserInterface/Icons/NeedsReviewIcon.swift index 0b0c671..2e99767 100644 --- a/Shared/UserInterface/Icons/NeedsReviewIcon.swift +++ b/Shared/UserInterface/Icons/NeedsReviewIcon.swift @@ -22,12 +22,12 @@ struct NeedsReviewIcon: View { } } -//struct NeedsReviewIcon_Previews: PreviewProvider { +// struct NeedsReviewIcon_Previews: PreviewProvider { // static var previews: some View { // NeedsReviewIcon() // .padding() // } -//} +// } struct NeedsReviewIcon_Previews: PreviewProvider { static var previews: some View { @@ -39,15 +39,13 @@ struct NeedsReviewIcon_Previews: PreviewProvider { .frame(height: 20) Text(12.description) - } .font(.largeTitle) - Text("Needs Review") .font(.title3) .foregroundStyle(Color.accentColor) - .padding(EdgeInsets(top: 4, leading: 10, bottom: 4, trailing: 10)) + .padding(EdgeInsets(top: 4, leading: 10, bottom: 4, trailing: 10)) .overlay( RoundedRectangle(cornerRadius: 20) .fill(Color.accentColor) @@ -58,4 +56,3 @@ struct NeedsReviewIcon_Previews: PreviewProvider { .padding() } } - diff --git a/Shared/UserInterface/Icons/ShareMergeRequestIcon.swift b/Shared/UserInterface/Icons/ShareMergeRequestIcon.swift index ff8b6f3..aa2c6cb 100644 --- a/Shared/UserInterface/Icons/ShareMergeRequestIcon.swift +++ b/Shared/UserInterface/Icons/ShareMergeRequestIcon.swift @@ -14,7 +14,7 @@ import UIKit #endif struct ShareMergeRequestIcon: View { - let MR: UniversalMergeRequest + let request: UniversalMergeRequest @State private var chosenEmoji: String = "" @State private var isVisible: Bool = false @@ -40,7 +40,7 @@ struct ShareMergeRequestIcon: View { .allowsHitTesting(false) } .frame(height: 20) - .onChange(of: chosenEmoji) { newValue, _ in + .onChange(of: chosenEmoji) { _, _ in let animation: Animation = .interpolatingSpring(stiffness: 130, damping: 12) withAnimation(animation) { isVisible = true @@ -57,8 +57,8 @@ struct ShareMergeRequestIcon: View { func copyToPasteboard() { let emoji = String.FriendlyEmojis.randomElement() ?? "🦆" let content = """ -\(MR.title ?? "") \(emoji) -\(MR.url?.absoluteString ?? "") +\(request.title ?? "") \(emoji) +\(request.url?.absoluteString ?? "") """ #if canImport(AppKit) let pasteboard = NSPasteboard.general diff --git a/Shared/UserInterface/Icons/WidgetApprovedReviewIcon.swift b/Shared/UserInterface/Icons/WidgetApprovedReviewIcon.swift index 118748b..bd4211a 100644 --- a/Shared/UserInterface/Icons/WidgetApprovedReviewIcon.swift +++ b/Shared/UserInterface/Icons/WidgetApprovedReviewIcon.swift @@ -16,7 +16,6 @@ struct WidgetApprovedReviewIcon: View { .help(String(localized: "Merge request approved")) .clipShape(Rectangle()) - if isHovering { Text("Approved") diff --git a/Shared/UserInterface/Icons/WidgetMRRowIcon.swift b/Shared/UserInterface/Icons/WidgetMRRowIcon.swift index 29de0b3..caf92cc 100644 --- a/Shared/UserInterface/Icons/WidgetMRRowIcon.swift +++ b/Shared/UserInterface/Icons/WidgetMRRowIcon.swift @@ -8,25 +8,23 @@ import SwiftUI struct WidgetMRRowIcon: View { - let MR: UniversalMergeRequest + let request: UniversalMergeRequest let providers: [GitProvider] var body: some View { HStack( spacing: 4) { if providers.count > 1 { - GitProviderView(provider: MR.account.provider) + GitProviderView(provider: request.account.provider) .frame(width: 18, height: 18, alignment: .center) } - - - - TitleWebLink(linkText: MR.title ?? "untitled", destination: MR.url, weight: .regular) + + TitleWebLink(linkText: request.title ?? "untitled", destination: request.url, weight: .regular) .multilineTextAlignment(.leading) .lineLimit(1) .truncationMode(.tail) .frame(maxWidth: .infinity, alignment: .leading) - - if MR.isApproved { + + if request.isApproved { WidgetApprovedReviewIcon() } } @@ -35,10 +33,10 @@ struct WidgetMRRowIcon: View { #Preview { VStack(spacing: 4) { - WidgetMRRowIcon(MR: .preview, providers: [.GitHub, .GitLab]) - WidgetMRRowIcon(MR: .previewGitHub, providers: [.GitHub, .GitLab]) - WidgetMRRowIcon(MR: .preview2, providers: [.GitHub, .GitLab]) - WidgetMRRowIcon(MR: .preview3, providers: [.GitHub, .GitLab]) + WidgetMRRowIcon(request: .preview, providers: [.GitHub, .GitLab]) + WidgetMRRowIcon(request: .previewGitHub, providers: [.GitHub, .GitLab]) + WidgetMRRowIcon(request: .preview2, providers: [.GitHub, .GitLab]) + WidgetMRRowIcon(request: .preview3, providers: [.GitHub, .GitLab]) } .scenePadding() } diff --git a/Shared/UserInterface/MainContentView.swift b/Shared/UserInterface/MainContentView.swift index e7de708..d06a0c8 100644 --- a/Shared/UserInterface/MainContentView.swift +++ b/Shared/UserInterface/MainContentView.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 19/10/2024. // - import SwiftUI import SwiftData import Get diff --git a/Shared/UserInterface/Models/GitLabISO8601DateFormatter.swift b/Shared/UserInterface/Models/GitLabISO8601DateFormatter.swift deleted file mode 100644 index 6872caf..0000000 --- a/Shared/UserInterface/Models/GitLabISO8601DateFormatter.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// File.swift -// -// -// Created by Stef Kors on 27/07/2022. -// - -import Foundation - -var GitLabISO8601DateFormatter: ISO8601DateFormatter { - let isoFormatter = ISO8601DateFormatter() - isoFormatter.formatOptions = [ - .withFullDate, - .withTime, - .withDashSeparatorInDate, - .withColonSeparatorInTime, - .withColonSeparatorInTimeZone, - .withFractionalSeconds, - .withTimeZone - ] - return isoFormatter -} - -extension Date { - static func fromGitLabISOString(_ string: String?) -> Date? { - guard let string, let date = GitLabISO8601DateFormatter.date(from: string) else { - return nil - } - return date - } -} diff --git a/Shared/UserInterface/Models/NetworkManagerGitHub.swift b/Shared/UserInterface/Models/NetworkManagerGitHub.swift index dd951d9..2a276e3 100644 --- a/Shared/UserInterface/Models/NetworkManagerGitHub.swift +++ b/Shared/UserInterface/Models/NetworkManagerGitHub.swift @@ -41,7 +41,6 @@ class NetworkManagerGitHub { ) } - // https://docs.github.com/en/graphql/overview/explorer // https://api.github.com/graphql func fetchAuthoredPullRequests(with account: Account) async throws -> [GitHub.PullRequestsNode]? { diff --git a/Shared/UserInterface/Models/NetworkManagerGitLab+repoLaunchPad.swift b/Shared/UserInterface/Models/NetworkManagerGitLab+repoLaunchPad.swift index bba9894..068894d 100644 --- a/Shared/UserInterface/Models/NetworkManagerGitLab+repoLaunchPad.swift +++ b/Shared/UserInterface/Models/NetworkManagerGitLab+repoLaunchPad.swift @@ -17,7 +17,7 @@ extension NetworkManagerGitLab { let repo = LaunchpadRepo( id: project.id, name: project.name ?? "", - image: await self.getProjectImage(with: account, project), + image: await self.getProjectImage(with: account, project), group: project.group?.fullName ?? project.namespace?.fullName ?? "", url: url, hasUpdatedSinceLaunch: true @@ -26,7 +26,6 @@ extension NetworkManagerGitLab { return repo } - fileprivate func getProjectImage(with account: Account, _ project: GitLab.TargetProject) async -> Data? { let id = project.id.components(separatedBy: "/").last ?? "" let branch = project.repository?.rootRef ?? "main" diff --git a/Shared/UserInterface/Models/NetworkManagerGitLab.swift b/Shared/UserInterface/Models/NetworkManagerGitLab.swift index ef4db21..4d9d175 100644 --- a/Shared/UserInterface/Models/NetworkManagerGitLab.swift +++ b/Shared/UserInterface/Models/NetworkManagerGitLab.swift @@ -24,7 +24,7 @@ class NetworkManagerGitLab { static func getQuery(_ type: QueryType) -> String { Self.buildQuery(target: "currentUser", type: type) } - + /// Return query for a specific user name /// - Parameters: /// - username: Username to fetch results for @@ -34,7 +34,7 @@ class NetworkManagerGitLab { let user = "user(username: \"\(username)\"" return Self.buildQuery(target: user, type: type) } - + /// Private method to build the GraphQL query based on the user information. Prefer getQuery methods instead /// - Parameters: /// - target: target string to fetch results for. Either string should be either `"currentUser"` or `"user(username: \"\(username)\""` @@ -52,7 +52,7 @@ class NetworkManagerGitLab { ("private_token", account.token) ]) } - + func authoredMergeRequestsReq(with account: Account) -> Request { Request.init(path: "/graphql", method: .post, query: [ ("query", Self.getQuery(.authoredMergeRequests)), @@ -66,22 +66,22 @@ class NetworkManagerGitLab { ("private_token", account.token) ]) } - + func fetch(with account: Account) async throws { /// Parallel? // await fetchLatestBranchPush() // try await fetchAuthoredMergeRequests(with: account) // try await fetchReviewRequestedMergeRequests(with: account) } - + func validateToken(instance: String, token: String) async -> AccessToken? { let accessTokenReq: Request = Request.init(path: "/v4/personal_access_tokens/self", query: [ ("private_token", token) ]) - + do { let response: AccessToken? = try await APIClient(baseURL: URL(string: "\(instance)/api")).send(accessTokenReq).value - + return response } catch { print(error.localizedDescription) @@ -154,8 +154,8 @@ extension NetworkManagerGitLab { let branchRef = event.pushData?.ref, let branchURL = URL(string: "\(project.url.absoluteString)/-/tree/\(branchRef)"), let createdAt = event.createdAt, - // Possible use Date.from(createdAt)? - let date = GitLabISO8601DateFormatter.date(from: createdAt) else { + // Possible use Date.from(createdAt) or GitLabISO8601DateFormatter? + let date = Date.from(createdAt) else { return nil } return NoticeMessage( diff --git a/Shared/UserInterface/Models/NetworkReachability.swift b/Shared/UserInterface/Models/NetworkReachability.swift index d0c5884..dddaac1 100644 --- a/Shared/UserInterface/Models/NetworkReachability.swift +++ b/Shared/UserInterface/Models/NetworkReachability.swift @@ -15,7 +15,7 @@ import Foundation func reachable(host: String) -> Bool { var res: UnsafeMutablePointer? - let n = getaddrinfo(host, nil, nil, &res) + let value = getaddrinfo(host, nil, nil, &res) freeaddrinfo(res) - return n == 0 + return value == 0 } diff --git a/Shared/UserInterface/Models/NetworkState.swift b/Shared/UserInterface/Models/NetworkState.swift index f90cf09..69f60d7 100644 --- a/Shared/UserInterface/Models/NetworkState.swift +++ b/Shared/UserInterface/Models/NetworkState.swift @@ -25,7 +25,7 @@ class NetworkState: ObservableObject { } return event } - + events = newEvents } } diff --git a/Shared/UserInterface/Models/NoticeState/NoticeMessage.swift b/Shared/UserInterface/Models/NoticeState/NoticeMessage.swift index 186858f..f571cfe 100644 --- a/Shared/UserInterface/Models/NoticeState/NoticeMessage.swift +++ b/Shared/UserInterface/Models/NoticeState/NoticeMessage.swift @@ -8,7 +8,7 @@ import Foundation import SwiftUI -struct NoticeMessage: Codable, Equatable, Hashable, Identifiable { +struct NoticeMessage: Codable, Equatable, Hashable, Identifiable { var id: UUID var label: String var statusCode: Int? @@ -17,7 +17,7 @@ struct NoticeMessage: Codable, Equatable, Hashable, Identifiable { var type: NoticeType var branchRef: String? var createdAt: Date - + init( id: UUID = UUID(), label: String, @@ -37,7 +37,7 @@ struct NoticeMessage: Codable, Equatable, Hashable, Identifiable { self.branchRef = branchRef self.createdAt = createdAt } - + var color: Color { switch self.type { case .branch: @@ -50,7 +50,7 @@ struct NoticeMessage: Codable, Equatable, Hashable, Identifiable { return .blue } } - + mutating func dismiss() { dismissed = true } diff --git a/Shared/UserInterface/Models/NoticeState/NoticeState.swift b/Shared/UserInterface/Models/NoticeState/NoticeState.swift index 9470c99..320804f 100644 --- a/Shared/UserInterface/Models/NoticeState/NoticeState.swift +++ b/Shared/UserInterface/Models/NoticeState/NoticeState.swift @@ -16,39 +16,39 @@ class NoticeState: ObservableObject { } } } - + func addNotice(notice: NoticeMessage) { // If the new notice is basically the same as the last notice, Don't add new notice for existingNotice in notices { if existingNotice.type == notice.type, existingNotice.statusCode == notice.statusCode, existingNotice.label == notice.label { - + // skip adding duplicate notice even if branch notice is dismissed if notice.type == .branch { return } - + if existingNotice.dismissed == false { print("skipping adding duplicate notice") return } } } - + notices.append(notice) } - + func dismissNotice(id: UUID) { let index = notices.lastIndex(where: { notice in notice.id == id }) - + if let index = index { notices[index].dismiss() } } - + func clearNetworkNotices() { for (index, notice) in notices.enumerated() { if notice.type == .network { @@ -56,9 +56,9 @@ class NoticeState: ObservableObject { } } } - + func clearAllNotices() { - for (index, _) in notices.enumerated() { + for index in notices.indices { notices[index].dismiss() } } diff --git a/Shared/UserInterface/Models/NotificationManager.swift b/Shared/UserInterface/Models/NotificationManager.swift index 5eb63d7..cd3b59d 100644 --- a/Shared/UserInterface/Models/NotificationManager.swift +++ b/Shared/UserInterface/Models/NotificationManager.swift @@ -43,7 +43,6 @@ class NotificationManager { options: [] ) - // Define the notification type let mrApprovalCategory = UNNotificationCategory( identifier: "MR_EVENT", @@ -58,7 +57,7 @@ class NotificationManager { notificationCenter.setNotificationCategories([mrApprovalCategory]) } - func sendNotification(title: String, subtitle: String?, userInfo: [AnyHashable : Any]? = nil) { + func sendNotification(title: String, subtitle: String?, userInfo: [AnyHashable: Any]? = nil) { let content = UNMutableNotificationContent() content.title = title @@ -83,7 +82,6 @@ class NotificationManager { } } - class GitLabNotificationDelegate: NSObject, UNUserNotificationCenterDelegate { @Environment(\.openURL) private var openURL @@ -106,7 +104,6 @@ class GitLabNotificationDelegate: NSObject, UNUserNotificationCenterDelegate { openURL(url) // NSWorkspace.shared.open(url) center.removeAllDeliveredNotifications() - break case UNNotificationDismissActionIdentifier: // do nothing @@ -116,7 +113,6 @@ class GitLabNotificationDelegate: NSObject, UNUserNotificationCenterDelegate { openURL(url) // NSWorkspace.shared.open(url) center.removeAllDeliveredNotifications() - break } // Always call the completion handler when done. completionHandler() diff --git a/Shared/UserInterface/Models/StructsGitHub.swift b/Shared/UserInterface/Models/StructsGitHub.swift index af7c381..119506c 100644 --- a/Shared/UserInterface/Models/StructsGitHub.swift +++ b/Shared/UserInterface/Models/StructsGitHub.swift @@ -15,7 +15,7 @@ class GitHub { var authoredMergeRequests: [GitHub.PullRequestsNode] { return self.data.viewer?.pullRequests?.nodes?.compactMap({ node in - if (node.locked == false) { + if node.locked == false { return node } else { return nil diff --git a/Shared/UserInterface/Models/StructsGitLab.swift b/Shared/UserInterface/Models/StructsGitLab.swift index b24fb41..219171d 100644 --- a/Shared/UserInterface/Models/StructsGitLab.swift +++ b/Shared/UserInterface/Models/StructsGitLab.swift @@ -92,7 +92,6 @@ class GitLab { targetProject: .preview ) - static let preview4 = MergeRequest( id: "gid://gitlab/MergeRequest/654", title: "Improve CI script performance by caching build artifacts", @@ -238,7 +237,6 @@ class GitLab { let node: HeadPipeline? } - // MARK: - Jobs struct Jobs: Codable, Equatable, Hashable { let edges: [JobsEdge]? @@ -632,12 +630,6 @@ class GitLab { case id, fullPath, fullName } - init(id: String, fullPath: String, fullName: String) { - self.id = id - self.fullPath = fullPath - self.fullName = fullName - } - static let preview = NameSpace(id: "gid://gitlab/Group/5", fullPath: "meta", fullName: "meta") } @@ -674,7 +666,7 @@ class GitLab { name: "meta", fullName: "meta", fullPath: "meta", - webURL: URL(string:"https://gitlab.com") + webURL: URL(string: "https://gitlab.com") ) } diff --git a/Shared/UserInterface/Models/gitlabISO8601DateFormatter.swift b/Shared/UserInterface/Models/gitlabISO8601DateFormatter.swift new file mode 100644 index 0000000..fd05f3d --- /dev/null +++ b/Shared/UserInterface/Models/gitlabISO8601DateFormatter.swift @@ -0,0 +1,29 @@ +// +// File.swift +// +// +// Created by Stef Kors on 27/07/2022. +// + +import Foundation + +extension Date { + + static func fromGitLabISOString(_ string: String?) -> Date? { + let isoFormatter = ISO8601DateFormatter() + isoFormatter.formatOptions = [ + .withFullDate, + .withTime, + .withDashSeparatorInDate, + .withColonSeparatorInTime, + .withColonSeparatorInTimeZone, + .withFractionalSeconds, + .withTimeZone + ] + guard let string, let date = isoFormatter.date(from: string) else { + return nil + } + return date + } + +} diff --git a/Shared/UserInterface/SwiftData/LaunchpadState.swift b/Shared/UserInterface/SwiftData/LaunchpadState.swift index 539f455..3c22dee 100644 --- a/Shared/UserInterface/SwiftData/LaunchpadState.swift +++ b/Shared/UserInterface/SwiftData/LaunchpadState.swift @@ -5,12 +5,11 @@ // Created by Stef Kors on 16/09/2022. // - import Foundation import SwiftUI import SwiftData -@Model final class LaunchpadRepo: Codable, Equatable, Hashable, Identifiable { +@Model final class LaunchpadRepo: Codable, Equatable, Hashable, Identifiable { init(id: String, name: String, image: Data? = nil, group: String, url: URL, hasUpdatedSinceLaunch: Bool = false) { self.id = id self.name = name @@ -19,18 +18,18 @@ import SwiftData self.url = url self.hasUpdatedSinceLaunch = hasUpdatedSinceLaunch } - + @Attribute(.unique) var id: String var name: String var image: Data? var group: String var url: URL var hasUpdatedSinceLaunch: Bool - + static func ==(lhs: LaunchpadRepo, rhs: LaunchpadRepo) -> Bool { return lhs.id == rhs.id } - + enum CodingKeys: CodingKey { case id case name @@ -38,10 +37,10 @@ import SwiftData case group case url } - + init(from decoder: Decoder) throws { let container: KeyedDecodingContainer = try decoder.container(keyedBy: LaunchpadRepo.CodingKeys.self) - + self.id = try container.decode(String.self, forKey: LaunchpadRepo.CodingKeys.id) self.name = try container.decode(String.self, forKey: LaunchpadRepo.CodingKeys.name) self.image = try container.decodeIfPresent(Data.self, forKey: LaunchpadRepo.CodingKeys.image) @@ -54,10 +53,10 @@ import SwiftData self.url = try container.decode(URL.self, forKey: LaunchpadRepo.CodingKeys.url) self.hasUpdatedSinceLaunch = false } - + func encode(to encoder: Encoder) throws { var container: KeyedEncodingContainer = encoder.container(keyedBy: LaunchpadRepo.CodingKeys.self) - + try container.encode(self.id, forKey: LaunchpadRepo.CodingKeys.id) try container.encode(self.name, forKey: LaunchpadRepo.CodingKeys.name) try container.encodeIfPresent(self.image, forKey: LaunchpadRepo.CodingKeys.image) diff --git a/Shared/UserInterface/SwiftData/UniversalMergeRequest.swift b/Shared/UserInterface/SwiftData/UniversalMergeRequest.swift index 976377e..8ac7297 100644 --- a/Shared/UserInterface/SwiftData/UniversalMergeRequest.swift +++ b/Shared/UserInterface/SwiftData/UniversalMergeRequest.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 31/10/2024. // - import SwiftUI import SwiftData @@ -133,7 +132,6 @@ import SwiftData } } - extension UniversalMergeRequest { static let preview = UniversalMergeRequest( request: .preview, @@ -171,11 +169,11 @@ extension UniversalMergeRequest { ) } -//extension MergeRequest: CustomDebugStringConvertible { +// extension MergeRequest: CustomDebugStringConvertible { // var debugDescription: String { // return "MergeRequest(mergerequestID: \(mergerequestID ?? "nil"), title: \(title ?? "nil"))" // } -//} +// } struct Approval: Codable, Equatable, Identifiable, Hashable { let id: String diff --git a/Shared/UserInterface/UserAvatarView.swift b/Shared/UserInterface/UserAvatarView.swift index 93c9d0f..81a8c77 100644 --- a/Shared/UserInterface/UserAvatarView.swift +++ b/Shared/UserInterface/UserAvatarView.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 10/10/2024. // - import SwiftUI struct UserAvatarView: View { diff --git a/Shared/UserInterface/UserInterface.swift b/Shared/UserInterface/UserInterface.swift index 9ceed4c..51d95d9 100644 --- a/Shared/UserInterface/UserInterface.swift +++ b/Shared/UserInterface/UserInterface.swift @@ -28,17 +28,17 @@ struct UserInterface: View { ) private var mergeRequests: [UniversalMergeRequest] @State private var selectedView: QueryType = .authoredMergeRequests - + @State private var timelineDate: Date = .now private let timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect() - + @EnvironmentObject private var noticeState: NoticeState @EnvironmentObject private var networkState: NetworkState - + private var filteredMergeRequests: [UniversalMergeRequest] { mergeRequests.filter { $0.type == selectedView } } - + var body: some View { VStack(alignment: .center, spacing: 10) { Picker(selection: $selectedView, content: { @@ -54,7 +54,7 @@ struct UserInterface: View { .padding(.horizontal, 6) .padding(.top, 6) .padding(.bottom, 0) - + if selectedView == .networkDebug { NetworkStateView() } else { @@ -66,7 +66,7 @@ struct UserInterface: View { ) } } - + .frame(maxHeight: .infinity, alignment: .top) .background(.regularMaterial) .onChange(of: selectedView) { _, newValue in @@ -84,7 +84,7 @@ struct UserInterface: View { await branchPushes() } } - .onReceive(timer) { time in + .onReceive(timer) { _ in timelineDate = .now Task { await fetchReviewRequestedMRs() @@ -94,7 +94,7 @@ struct UserInterface: View { } } } - + /// TODO: Cleanup and move both into the same function @MainActor private func fetchReviewRequestedMRs() async { @@ -115,7 +115,7 @@ struct UserInterface: View { } } } - + @MainActor private func fetchAuthoredMRs() async { for account in accounts { @@ -209,14 +209,14 @@ struct UserInterface: View { try? modelContext.save() } } - + @MainActor private func fetchRepos() async { for account in accounts { if account.provider == .GitLab { - let ids = Array(Set(mergeRequests.compactMap { mr in - if mr.provider == .GitLab { - return mr.mergeRequest?.targetProject?.id.split(separator: "/").last + let ids = Array(Set(mergeRequests.compactMap { request in + if request.provider == .GitLab { + return request.mergeRequest?.targetProject?.id.split(separator: "/").last } else { return nil } @@ -236,7 +236,7 @@ struct UserInterface: View { } } } - + @MainActor private func branchPushes() async { for account in accounts { @@ -247,10 +247,10 @@ struct UserInterface: View { } if let notice { - if notice.type == .branch, let branch = notice.branchRef { + if notice.type == .branch, let branch = notice.branchRef { - let matchedMR = filteredMergeRequests.first { mr in - return mr.sourceBranch == branch + let matchedMR = filteredMergeRequests.first { request in + return request.sourceBranch == branch } let alreadyHasMR = matchedMR != nil @@ -284,9 +284,9 @@ struct UserInterface: View { event.response = error.localizedDescription networkState.update(event) } - + return nil - + } } @@ -302,8 +302,8 @@ struct UserInterface: View { .scenePadding() } -//NotificationManager.shared.sendNotification( +// NotificationManager.shared.sendNotification( // title: title, // subtitle: "\(reference) is approved by \(approvers.formatted())", // userInfo: userInfo -//) +// ) diff --git a/Shared/UserInterface/Views/AddAccountView.swift b/Shared/UserInterface/Views/AddAccountView.swift index dde5159..8fdf927 100644 --- a/Shared/UserInterface/Views/AddAccountView.swift +++ b/Shared/UserInterface/Views/AddAccountView.swift @@ -44,7 +44,6 @@ struct AddAccountView: View { AddAccountView() } - #Preview("iOS") { VStack { Spacer() diff --git a/Shared/UserInterface/Views/AutoSizingWebLinks.swift b/Shared/UserInterface/Views/AutoSizingWebLinks.swift index 86989d8..8219a79 100644 --- a/Shared/UserInterface/Views/AutoSizingWebLinks.swift +++ b/Shared/UserInterface/Views/AutoSizingWebLinks.swift @@ -8,12 +8,12 @@ import SwiftUI struct GitLabAutoSizingWebLinks: View { - var MR: GitLab.MergeRequest + var request: GitLab.MergeRequest // spaced with "thin width space" // https://www.compart.com/en/unicode/U+2009 var group: String { - if let name = MR.targetProject?.group?.fullPath?.trimmingPrefix("/"), !name.isEmpty { + if let name = request.targetProject?.group?.fullPath?.trimmingPrefix("/"), !name.isEmpty { return name + " / " } @@ -21,7 +21,7 @@ struct GitLabAutoSizingWebLinks: View { } var path: String { - if let name = MR.targetProject?.path?.trimmingPrefix("/"), !name.isEmpty { + if let name = request.targetProject?.path?.trimmingPrefix("/"), !name.isEmpty { return name + " / " } @@ -29,7 +29,7 @@ struct GitLabAutoSizingWebLinks: View { } var reference: String { - if let name = MR.reference?.trimmingPrefix("/"), !name.isEmpty { + if let name = request.reference?.trimmingPrefix("/"), !name.isEmpty { return String(name) } @@ -40,17 +40,17 @@ struct GitLabAutoSizingWebLinks: View { ViewThatFits(in: .horizontal) { WebLink( linkText: group + path + reference, - destination: MR.targetProject?.webURL + destination: request.targetProject?.webURL ) WebLink( linkText: path + reference, - destination: MR.targetProject?.webURL + destination: request.targetProject?.webURL ) WebLink( linkText: reference, - destination: MR.targetProject?.webURL + destination: request.targetProject?.webURL ) } @@ -120,12 +120,12 @@ struct GitHubAutoSizingWebLinks: View { } struct AutoSizingWebLinks: View { - var MR: UniversalMergeRequest + var request: UniversalMergeRequest var body: some View { - if let request = MR.mergeRequest { - GitLabAutoSizingWebLinks(MR: request) - } else if let request = MR.pullRequest { + if let request = request.mergeRequest { + GitLabAutoSizingWebLinks(request: request) + } else if let request = request.pullRequest { GitHubAutoSizingWebLinks(MR: request) } } @@ -133,16 +133,16 @@ struct AutoSizingWebLinks: View { #Preview { VStack(alignment: .leading) { - AutoSizingWebLinks(MR: .preview) + AutoSizingWebLinks(request: .preview) .frame(width: 40, alignment: .leading) .border(Color.blue) - AutoSizingWebLinks(MR: .preview) + AutoSizingWebLinks(request: .preview) .frame(width: 110, alignment: .leading) .border(Color.blue) - AutoSizingWebLinks(MR: .preview) + AutoSizingWebLinks(request: .preview) .frame(width: 190, alignment: .leading) .border(Color.blue) - AutoSizingWebLinks(MR: .preview) + AutoSizingWebLinks(request: .preview) .frame(width: 290, alignment: .leading) .border(Color.blue) } diff --git a/Shared/UserInterface/Views/AvatarRowView.swift b/Shared/UserInterface/Views/AvatarRowView.swift index 8ed535d..f62aca6 100644 --- a/Shared/UserInterface/Views/AvatarRowView.swift +++ b/Shared/UserInterface/Views/AvatarRowView.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 21/10/2024. // - import SwiftUI struct AvatarRowView: View { @@ -26,7 +25,6 @@ struct AvatarRowView: View { } } - var body: some View { HStack(spacing: -4) { ForEach(Array(approvers.enumerated()), id: \.element, content: { index, author in @@ -83,7 +81,6 @@ struct AvatarRowView: View { AvatarRowView(approvedBy: [.preview2, .preview3, .preview2, .preview3], account: .preview) .scenePadding() - AvatarRowView(approvedBy: [.preview, .preview2, .preview3, .preview2, .preview3, .preview, .preview2, .preview3, .preview2, .preview3], account: .preview) .scenePadding() diff --git a/Shared/UserInterface/Views/DoubleLineMergeRequestSubRowView.swift b/Shared/UserInterface/Views/DoubleLineMergeRequestSubRowView.swift index fb876b0..099f0cf 100644 --- a/Shared/UserInterface/Views/DoubleLineMergeRequestSubRowView.swift +++ b/Shared/UserInterface/Views/DoubleLineMergeRequestSubRowView.swift @@ -5,32 +5,31 @@ // Created by Stef Kors on 17/10/2024. // - import SwiftUI struct DoubleLineMergeRequestSubRowView: View { - var MR: UniversalMergeRequest + var request: UniversalMergeRequest var body: some View { VStack(alignment: .leading) { HStack(alignment: .center, spacing: 4) { - GitProviderView(provider: MR.account.provider) + GitProviderView(provider: request.account.provider) .frame(width: 18, height: 18, alignment: .center) - AutoSizingWebLinks(MR: MR) + AutoSizingWebLinks(request: request) Spacer() } HStack(alignment: .center, spacing: 4) { - if let count = MR.discussionCount, count > 1 { + if let count = request.discussionCount, count > 1 { DiscussionCountIcon(count: count) } - MergeStatusView(MR: MR) + MergeStatusView(request: request) // TODO: support github pipelines - if let pipeline = MR.mergeRequest?.headPipeline { - PipelineView(pipeline: pipeline, instance: MR.account.instance) + if let pipeline = request.mergeRequest?.headPipeline { + PipelineView(pipeline: pipeline, instance: request.account.instance) } } } diff --git a/Shared/UserInterface/Views/GitHubAccountView.swift b/Shared/UserInterface/Views/GitHubAccountView.swift index 634bfcd..aae840c 100644 --- a/Shared/UserInterface/Views/GitHubAccountView.swift +++ b/Shared/UserInterface/Views/GitHubAccountView.swift @@ -7,7 +7,7 @@ import SwiftUI -fileprivate enum SubmitState { +private enum SubmitState { case readyToSubmit case validating case success(token: String) @@ -35,16 +35,15 @@ struct GitHubAccountView: View { token.isEmpty || instance.isEmpty } - var body: some View { Section { TextField("GitHub Token", text: $token, prompt: Text("Enter token here...")) - .onChange(of: token, initial: false) { oldValue, newValue in + .onChange(of: token, initial: false) { _, _ in state = .readyToSubmit } TextField("Base URL", text: $instance, prompt: Text("https://www.gitlab.com")) - .onChange(of: instance, initial: false) { oldValue, newValue in + .onChange(of: instance, initial: false) { _, _ in state = .readyToSubmit } @@ -60,7 +59,6 @@ struct GitHubAccountView: View { dismiss() } - switch state { case .readyToSubmit: Button(action: handleSubmit, label: { @@ -87,7 +85,6 @@ struct GitHubAccountView: View { } } - func handleSubmit() { Task { withAnimation { @@ -129,7 +126,6 @@ struct GitHubAccountView: View { } } - #Preview { Form { GitHubAccountView() diff --git a/Shared/UserInterface/Views/GitLabAccountView.swift b/Shared/UserInterface/Views/GitLabAccountView.swift index 979cf40..8294033 100644 --- a/Shared/UserInterface/Views/GitLabAccountView.swift +++ b/Shared/UserInterface/Views/GitLabAccountView.swift @@ -5,10 +5,9 @@ // Created by Stef Kors on 30/10/2024. // - import SwiftUI -fileprivate enum SubmitState { +private enum SubmitState { case readyToSubmit case validating case success(token: AccessToken) @@ -36,24 +35,22 @@ struct GitLabAccountView: View { token.isEmpty || instance.isEmpty } - var body: some View { Section { TextField("GitLab Token", text: $token, prompt: Text("Enter token here...")) - .onChange(of: token, initial: false) { oldValue, newValue in + .onChange(of: token, initial: false) { _, _ in state = .readyToSubmit } // Menu("Options") { TextField("Base URL", text: $instance, prompt: Text("https://www.gitlab.com")) - .onChange(of: instance, initial: false) { oldValue, newValue in + .onChange(of: instance, initial: false) { _, _ in state = .readyToSubmit } // Button("custom item", action: {}) // } - TokenInformationView(token: tokenInformation) } header: { @@ -66,7 +63,6 @@ struct GitLabAccountView: View { dismiss() } - switch state { case .readyToSubmit: Button(action: handleSubmit, label: { @@ -93,7 +89,6 @@ struct GitLabAccountView: View { } } - func handleSubmit() { Task { withAnimation { @@ -125,7 +120,6 @@ struct GitLabAccountView: View { } } - #Preview { Form { GitLabAccountView() diff --git a/Shared/UserInterface/Views/HorizontalMergeRequestSubRowView.swift b/Shared/UserInterface/Views/HorizontalMergeRequestSubRowView.swift index 62bf58b..11125e7 100644 --- a/Shared/UserInterface/Views/HorizontalMergeRequestSubRowView.swift +++ b/Shared/UserInterface/Views/HorizontalMergeRequestSubRowView.swift @@ -5,27 +5,26 @@ // Created by Stef Kors on 17/10/2024. // - import SwiftUI struct HorizontalMergeRequestSubRowView: View { - var MR: UniversalMergeRequest + var request: UniversalMergeRequest var body: some View { HStack(alignment: .center, spacing: 4) { - GitProviderView(provider: MR.account.provider) + GitProviderView(provider: request.account.provider) .frame(width: 18, height: 18, alignment: .center) - AutoSizingWebLinks(MR: MR) + AutoSizingWebLinks(request: request) Spacer() - if let count = MR.discussionCount, count > 1 { + if let count = request.discussionCount, count > 1 { DiscussionCountIcon(count: count) } - MergeStatusView(MR: MR) + MergeStatusView(request: request) // TODO: support github pipelines - if let pipeline = MR.mergeRequest?.headPipeline { - PipelineView(pipeline: pipeline, instance: MR.account.instance) + if let pipeline = request.mergeRequest?.headPipeline { + PipelineView(pipeline: pipeline, instance: request.account.instance) } } } @@ -33,11 +32,11 @@ struct HorizontalMergeRequestSubRowView: View { #Preview { VStack { - HorizontalMergeRequestSubRowView(MR: .preview) - HorizontalMergeRequestSubRowView(MR: .preview2) - HorizontalMergeRequestSubRowView(MR: .preview3) - HorizontalMergeRequestSubRowView(MR: .preview4) - HorizontalMergeRequestSubRowView(MR: .previewGitHub) + HorizontalMergeRequestSubRowView(request: .preview) + HorizontalMergeRequestSubRowView(request: .preview2) + HorizontalMergeRequestSubRowView(request: .preview3) + HorizontalMergeRequestSubRowView(request: .preview4) + HorizontalMergeRequestSubRowView(request: .previewGitHub) } .scenePadding() } diff --git a/Shared/UserInterface/Views/LastUpdateMessageView.swift b/Shared/UserInterface/Views/LastUpdateMessageView.swift index 90adf74..6d1a1aa 100644 --- a/Shared/UserInterface/Views/LastUpdateMessageView.swift +++ b/Shared/UserInterface/Views/LastUpdateMessageView.swift @@ -45,8 +45,7 @@ struct LastUpdateMessageView: View { #if os(macOS) if #available(macOS 13.0, *) { NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil) - } - else { + } else { NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil) } #endif diff --git a/Shared/UserInterface/Views/LaunchPadView.swift b/Shared/UserInterface/Views/LaunchPadView.swift index 51dfdf2..5c18e2d 100644 --- a/Shared/UserInterface/Views/LaunchPadView.swift +++ b/Shared/UserInterface/Views/LaunchPadView.swift @@ -12,7 +12,7 @@ struct LaunchpadView: View { var body: some View { ScrollView(.horizontal) { - HStack() { + HStack { ForEach(repos.reversed(), id: \.id) { repo in LaunchpadItem(repo: repo) } diff --git a/Shared/UserInterface/Views/LaunchpadImage.swift b/Shared/UserInterface/Views/LaunchpadImage.swift index 6c531ee..75cfce5 100644 --- a/Shared/UserInterface/Views/LaunchpadImage.swift +++ b/Shared/UserInterface/Views/LaunchpadImage.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 17/10/2024. // - import SwiftUI struct LaunchpadImage: View { diff --git a/Shared/UserInterface/Views/LaunchpadItem.swift b/Shared/UserInterface/Views/LaunchpadItem.swift index a58eef0..b36c641 100644 --- a/Shared/UserInterface/Views/LaunchpadItem.swift +++ b/Shared/UserInterface/Views/LaunchpadItem.swift @@ -12,7 +12,7 @@ struct LaunchpadItem: View { @Environment(\.openURL) private var openURL @Environment(\.dismissWindow) private var dismissWindow - + @State private var isHovering = false var body: some View { @@ -20,7 +20,7 @@ struct LaunchpadItem: View { // // TODO: // print("todo: set filter") // } label: { - HStack() { + HStack { LaunchpadImage(repo: repo) VStack(alignment: .leading) { diff --git a/Shared/UserInterface/Views/MRTitleView.swift b/Shared/UserInterface/Views/MRTitleView.swift index ace9b70..f21e69f 100644 --- a/Shared/UserInterface/Views/MRTitleView.swift +++ b/Shared/UserInterface/Views/MRTitleView.swift @@ -5,7 +5,6 @@ // Created by Stef Kors on 17/10/2024. // - import SwiftUI struct MRTitleView: View { diff --git a/Shared/UserInterface/Views/MergeRequestLabelView.swift b/Shared/UserInterface/Views/MergeRequestLabelView.swift index dd1fab6..393aaed 100644 --- a/Shared/UserInterface/Views/MergeRequestLabelView.swift +++ b/Shared/UserInterface/Views/MergeRequestLabelView.swift @@ -8,16 +8,16 @@ import SwiftUI struct MergeRequestLabelView: View { - var MR: GitLab.MergeRequest + var request: GitLab.MergeRequest var body: some View { VStack(alignment: .leading, spacing: 5) { - TitleWebLink(linkText: MR.title ?? "untitled", destination: MR.webUrl, isDraft: MR.title?.isDraft ?? false) + TitleWebLink(linkText: request.title ?? "untitled", destination: request.webUrl, isDraft: request.title?.isDraft ?? false) /// hacks we actually want line wrapping .multilineTextAlignment(.leading) .truncationMode(.middle) WebLink( - linkText: "\(MR.targetProject?.path ?? "")\("/")\(MR.targetProject?.group?.fullPath ?? "")\(MR.reference ?? "")", - destination: MR.targetProject?.webURL + linkText: "\(request.targetProject?.path ?? "")\("/")\(request.targetProject?.group?.fullPath ?? "")\(request.reference ?? "")", + destination: request.targetProject?.webURL ) }.fixedSize(horizontal: false, vertical: true) } diff --git a/Shared/UserInterface/Views/MergeRequestRowView.swift b/Shared/UserInterface/Views/MergeRequestRowView.swift index bcd6644..9bad146 100644 --- a/Shared/UserInterface/Views/MergeRequestRowView.swift +++ b/Shared/UserInterface/Views/MergeRequestRowView.swift @@ -8,25 +8,25 @@ import SwiftUI struct MergeRequestRowView: View { - var MR: UniversalMergeRequest + var request: UniversalMergeRequest @Environment(\.openURL) private var openURL @Environment(\.dismissWindow) private var dismissWindow - + var body: some View { Button { - if let url = MR.url { + if let url = request.url { openURL(url) dismissWindow() } } label: { VStack(alignment: .leading, spacing: 5) { - MRTitleView(linkText: MR.title ?? "untitled", isDraft: MR.isDraft) + MRTitleView(linkText: request.title ?? "untitled", isDraft: request.isDraft) .multilineTextAlignment(.leading) .truncationMode(.middle) .padding(.trailing) - HorizontalMergeRequestSubRowView(MR: MR) + HorizontalMergeRequestSubRowView(request: request) } } .buttonStyle(.shaded) @@ -36,23 +36,23 @@ struct MergeRequestRowView: View { #Preview { VStack(alignment: .leading, spacing: 50, content: { VStack(alignment: .leading, content: { - MergeRequestRowView(MR: .preview) - MergeRequestRowView(MR: .preview3) - MergeRequestRowView(MR: .preview2) + MergeRequestRowView(request: .preview) + MergeRequestRowView(request: .preview3) + MergeRequestRowView(request: .preview2) }) .frame(width: 190) - + VStack(alignment: .leading, content: { - MergeRequestRowView(MR: .preview) - MergeRequestRowView(MR: .preview3) - MergeRequestRowView(MR: .preview2) + MergeRequestRowView(request: .preview) + MergeRequestRowView(request: .preview3) + MergeRequestRowView(request: .preview2) }) .frame(width: 290) - + VStack(alignment: .leading, content: { - MergeRequestRowView(MR: .preview) - MergeRequestRowView(MR: .preview3) - MergeRequestRowView(MR: .preview2) + MergeRequestRowView(request: .preview) + MergeRequestRowView(request: .preview3) + MergeRequestRowView(request: .preview2) }) }) .scenePadding() diff --git a/Shared/UserInterface/Views/MergeStatusView.swift b/Shared/UserInterface/Views/MergeStatusView.swift index 23f696d..31a2e85 100644 --- a/Shared/UserInterface/Views/MergeStatusView.swift +++ b/Shared/UserInterface/Views/MergeStatusView.swift @@ -9,38 +9,37 @@ import SwiftUI import Foundation struct MergeStatusView: View { - var MR: UniversalMergeRequest + var request: UniversalMergeRequest private var isOnMergeTrain: Bool { - MR.mergeRequest?.headPipeline?.mergeRequestEventType == .mergeTrain + request.mergeRequest?.headPipeline?.mergeRequestEventType == .mergeTrain } - + private var approvers: [Approval]? { - MR.approvals + request.approvals } - + @Environment(\.isInWidget) private var isInWidget - + var body: some View { if isOnMergeTrain { MergeTrainIcon() } else if let approvers = approvers, !approvers.isEmpty { - ApprovedReviewIcon(approvedBy: approvers, account: MR.account) - } else if !isInWidget, !MR.isDraft { - ShareMergeRequestIcon(MR: MR) + ApprovedReviewIcon(approvedBy: approvers, account: request.account) + } else if !isInWidget, !request.isDraft { + ShareMergeRequestIcon(request: request) } else { // NeedsReviewIcon() } } } - extension String { - func contains(_ find: String) -> Bool{ + func contains(_ find: String) -> Bool { return self.range(of: find) != nil } - - func containsIgnoringCase(_ find: String) -> Bool{ + + func containsIgnoringCase(_ find: String) -> Bool { return self.range(of: find, options: .caseInsensitive) != nil } } diff --git a/Shared/UserInterface/Views/NoticeViews/BaseNoticeItem.swift b/Shared/UserInterface/Views/NoticeViews/BaseNoticeItem.swift index 2828c3b..e0020ef 100644 --- a/Shared/UserInterface/Views/NoticeViews/BaseNoticeItem.swift +++ b/Shared/UserInterface/Views/NoticeViews/BaseNoticeItem.swift @@ -137,7 +137,7 @@ struct BaseNoticeItem_Previews: PreviewProvider { .padding(.horizontal) // needed to render in the correct colorScheme .colorScheme(.dark) - + let renderer = ImageRenderer(content: renderView) renderer.scale = 4.0 renderer.isOpaque = false diff --git a/Shared/UserInterface/Views/NoticeViews/NoticeListView.swift b/Shared/UserInterface/Views/NoticeViews/NoticeListView.swift index c9fa215..d2c86b2 100644 --- a/Shared/UserInterface/Views/NoticeViews/NoticeListView.swift +++ b/Shared/UserInterface/Views/NoticeViews/NoticeListView.swift @@ -7,10 +7,9 @@ import SwiftUI - struct NoticeListView: View { @EnvironmentObject var noticeState: NoticeState - + var body: some View { if !noticeState.notices.isEmpty { VStack { diff --git a/Shared/UserInterface/Views/NotificationViews/CIJobsNotificationView.swift b/Shared/UserInterface/Views/NotificationViews/CIJobsNotificationView.swift index adaa6aa..c150285 100644 --- a/Shared/UserInterface/Views/NotificationViews/CIJobsNotificationView.swift +++ b/Shared/UserInterface/Views/NotificationViews/CIJobsNotificationView.swift @@ -13,7 +13,7 @@ import SwiftUI init (stages: [GitLab.FluffyNode?]?) { self.stages = stages ?? [] } - + var body: some View { HStack(alignment: .top, spacing: 0) { ForEach(stages.indices, id: \.self) { index in @@ -35,11 +35,10 @@ import SwiftUI } } } - + } } - struct CIJobsNotificationView_Previews: PreviewProvider { static var previews: some View { VStack { @@ -51,7 +50,7 @@ struct CIJobsNotificationView_Previews: PreviewProvider { // .padding() // needed to render in the correct colorScheme .colorScheme(.dark) - + let renderer = ImageRenderer(content: renderView) renderer.scale = 4.0 renderer.isOpaque = false diff --git a/Shared/UserInterface/Views/PipelineView.swift b/Shared/UserInterface/Views/PipelineView.swift index 505bdb4..7a3e630 100644 --- a/Shared/UserInterface/Views/PipelineView.swift +++ b/Shared/UserInterface/Views/PipelineView.swift @@ -15,24 +15,24 @@ struct Values { struct PipelineView: View { var pipeline: GitLab.HeadPipeline var instance: String? - + private var stages: [GitLab.FluffyNode] { pipeline.stages?.edges?.map({ $0.node }).compactMap({ $0 }) ?? [] } - + private var allSucceeded: Bool { pipeline.status == .success && !isHovering } - + private var spacing: CGFloat { allSucceeded ? -14 : 0 } - + @State private var isHovering: Bool = false - + var body: some View { HStack(alignment: .center, spacing: spacing) { - + ForEach(Array(stages.enumerated()), id: \.element, content: { index, stage in HStack(spacing: 0) { CIJobsView(stage: stage, instance: instance) @@ -56,7 +56,7 @@ struct PipelineView: View { .animation(.snappy.delay(isHovering ? 0.05 : 0), value: isHovering) .zIndex(1) } - + } .zIndex(Double(stages.count - index)) }) @@ -69,7 +69,6 @@ struct PipelineView: View { } } - #Preview { VStack(alignment: .trailing) { PipelineView(pipeline: .previewTestFailed, instance: nil) diff --git a/Shared/UserInterface/Views/PlainMergeRequestList.swift b/Shared/UserInterface/Views/PlainMergeRequestList.swift index 3464cfb..3811d10 100644 --- a/Shared/UserInterface/Views/PlainMergeRequestList.swift +++ b/Shared/UserInterface/Views/PlainMergeRequestList.swift @@ -16,7 +16,7 @@ struct PlainMergeRequestList: View { var body: some View { ForEach(mergeRequests, id: \.id) { mergeRequest in - MergeRequestRowView(MR: mergeRequest) + MergeRequestRowView(request: mergeRequest) .transition(.opacity) // .listRowSeparator(.visible) // .listRowSeparatorTint(Color.secondary.opacity(0.2)) diff --git a/Shared/UserInterface/Views/ProjectLink.swift b/Shared/UserInterface/Views/ProjectLink.swift index 5bee31a..711bc4d 100644 --- a/Shared/UserInterface/Views/ProjectLink.swift +++ b/Shared/UserInterface/Views/ProjectLink.swift @@ -26,8 +26,6 @@ struct ProjectLink: View { [reference].compactMap({ $0 }).joined(separator: "/") } - - var body: some View { ViewThatFits { WebLink( diff --git a/Shared/UserInterface/Views/SectionedMergeRequestList.swift b/Shared/UserInterface/Views/SectionedMergeRequestList.swift index de2acf5..45464e7 100644 --- a/Shared/UserInterface/Views/SectionedMergeRequestList.swift +++ b/Shared/UserInterface/Views/SectionedMergeRequestList.swift @@ -15,7 +15,7 @@ struct SectionedMergeRequestList: View { ForEach(accounts) { account in Section(header: Text(account.instance)) { ForEach(account.requests, id: \.id) { mergeRequest in - MergeRequestRowView(MR: mergeRequest) + MergeRequestRowView(request: mergeRequest) .padding(.bottom, 4) .listRowSeparator(.visible) .listRowSeparatorTint(Color.secondary.opacity(0.2)) diff --git a/Shared/UserInterface/Views/SettingsViews/AccountSettingsView.swift b/Shared/UserInterface/Views/SettingsViews/AccountSettingsView.swift index 1a50828..2450810 100644 --- a/Shared/UserInterface/Views/SettingsViews/AccountSettingsView.swift +++ b/Shared/UserInterface/Views/SettingsViews/AccountSettingsView.swift @@ -20,7 +20,7 @@ struct AlertDetails: Identifiable { @Query var accounts: [Account] @State private var showingAlert: Bool = false - @State private var details: AlertDetails? = nil + @State private var details: AlertDetails? @State private var showCreateSheet: Bool = false let alertTitle: String = "Confirm deletion" var body: some View { @@ -36,7 +36,7 @@ struct AlertDetails: Identifiable { .frame(width: 25, height: 25, alignment: .center) AccountRow(account: account) Spacer() - + Button(role: .destructive) { showAlert(for: account) } label: { diff --git a/Shared/UserInterface/Views/SettingsViews/SettingsView.swift b/Shared/UserInterface/Views/SettingsViews/SettingsView.swift index 5883791..f9b4954 100644 --- a/Shared/UserInterface/Views/SettingsViews/SettingsView.swift +++ b/Shared/UserInterface/Views/SettingsViews/SettingsView.swift @@ -11,7 +11,7 @@ import SwiftData struct SettingsView: View { // Persistance objects private enum Tabs: Hashable { - case Account + case account } init() { } @@ -23,7 +23,7 @@ struct SettingsView: View { Image(systemName: "person.badge.shield.checkmark.fill") Text("Account") } - .tag(Tabs.Account) + .tag(Tabs.account) } .frame(idealWidth: 600, idealHeight: 500) .navigationTitle("Settings") diff --git a/Shared/UserInterface/Views/TitleWebLink.swift b/Shared/UserInterface/Views/TitleWebLink.swift index e8c9eb0..e5ac142 100644 --- a/Shared/UserInterface/Views/TitleWebLink.swift +++ b/Shared/UserInterface/Views/TitleWebLink.swift @@ -14,7 +14,6 @@ struct TitleWebLink: View { var weight: Font.Weight = .bold var isDraft: Bool = false - var body: some View { if let url = destination { Link(destination: url, label: { diff --git a/Shared/UserInterface/Views/WebLink.swift b/Shared/UserInterface/Views/WebLink.swift index 6c658d2..f94ac4c 100644 --- a/Shared/UserInterface/Views/WebLink.swift +++ b/Shared/UserInterface/Views/WebLink.swift @@ -10,9 +10,9 @@ import SwiftUI struct WebLink: View { var linkText: String var destination: URL? - + @State private var isHovering = false - + var body: some View { if let url = destination { Link(destination: url, label: {