Skip to content

Commit dd9869b

Browse files
authored
Merge pull request #25 from tryboxx/SNLB-24/feature/detailedPreview
[SNLB-24] Add more details to preview view
2 parents d6eb93a + 4a70baa commit dd9869b

File tree

12 files changed

+257
-57
lines changed

12 files changed

+257
-57
lines changed

SnippetsLibrary.xcodeproj/project.pbxproj

+8
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@
106106
B8C549BC26FFA71300720E62 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C549BB26FFA71300720E62 /* AppView.swift */; };
107107
B8C549C426FFBA8600720E62 /* View+Skeletonable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C549C326FFBA8600720E62 /* View+Skeletonable.swift */; };
108108
B8C8755926FD2AB600DE4474 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B88D4A3526F4E34900164BF5 /* GoogleService-Info.plist */; };
109+
B8CB01072716613F00D3A6DD /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CB01062716613F00D3A6DD /* String+Extensions.swift */; };
110+
B8CB01092716681700D3A6DD /* AppAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CB01082716681700D3A6DD /* AppAlert.swift */; };
109111
B8CE1CAB26FD4193004AD5D5 /* DisabledCommandGroupButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CE1CAA26FD4193004AD5D5 /* DisabledCommandGroupButton.swift */; };
110112
B8CE1CAE26FD431E004AD5D5 /* URLFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CE1CAD26FD431E004AD5D5 /* URLFactory.swift */; };
111113
B8CE1CB026FD43B5004AD5D5 /* URLType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CE1CAF26FD43B5004AD5D5 /* URLType.swift */; };
@@ -259,6 +261,8 @@
259261
B8C549B926FF9C0800720E62 /* NetworkObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkObserver.swift; sourceTree = "<group>"; };
260262
B8C549BB26FFA71300720E62 /* AppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = "<group>"; };
261263
B8C549C326FFBA8600720E62 /* View+Skeletonable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Skeletonable.swift"; sourceTree = "<group>"; };
264+
B8CB01062716613F00D3A6DD /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
265+
B8CB01082716681700D3A6DD /* AppAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAlert.swift; sourceTree = "<group>"; };
262266
B8CE1CAA26FD4193004AD5D5 /* DisabledCommandGroupButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisabledCommandGroupButton.swift; sourceTree = "<group>"; };
263267
B8CE1CAD26FD431E004AD5D5 /* URLFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLFactory.swift; sourceTree = "<group>"; };
264268
B8CE1CAF26FD43B5004AD5D5 /* URLType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLType.swift; sourceTree = "<group>"; };
@@ -472,6 +476,7 @@
472476
B82561EC26E8C89A0040A67E /* AppSheet.swift */,
473477
B8C549BB26FFA71300720E62 /* AppView.swift */,
474478
B85AC92D2702153E00A008A6 /* AppMenu.swift */,
479+
B8CB01082716681700D3A6DD /* AppAlert.swift */,
475480
);
476481
path = Application;
477482
sourceTree = "<group>";
@@ -523,6 +528,7 @@
523528
B85AC92F2702158300A008A6 /* AppDelegate+NSMenuDelegate.swift */,
524529
B81B0876270232B600E59F86 /* NSNotification+Name.swift */,
525530
B81B0878270245CE00E59F86 /* AppMenu+HideWindow.swift */,
531+
B8CB01062716613F00D3A6DD /* String+Extensions.swift */,
526532
);
527533
path = Extensions;
528534
sourceTree = "<group>";
@@ -1015,6 +1021,7 @@
10151021
B8EB5ADB26F0076C00BE3EF6 /* PlistCodingKeys.swift in Sources */,
10161022
B82B5586270007C500DE4766 /* DatabaseReference+Timeout.swift in Sources */,
10171023
B82B55822700014600DE4766 /* StartView+Equatable.swift in Sources */,
1024+
B8CB01092716681700D3A6DD /* AppAlert.swift in Sources */,
10181025
B88D7A6126F797F000B114F6 /* UserDefaultsService.swift in Sources */,
10191026
B82B55802700011000DE4766 /* SnippetsLibraryView+Equatable.swift in Sources */,
10201027
B82561EB26E8C7F00040A67E /* SnippetsLibraryViewModel.swift in Sources */,
@@ -1079,6 +1086,7 @@
10791086
B88BB45626F55DDB00747631 /* LogsService.swift in Sources */,
10801087
B88D7A6326F7A5C000B114F6 /* SnippetPlist+Dictonary.swift in Sources */,
10811088
B832886D27160F17006BD465 /* SnippetsFetchingType.swift in Sources */,
1089+
B8CB01072716613F00D3A6DD /* String+Extensions.swift in Sources */,
10821090
B8546F3C27077C310043A99F /* SnippetsLibraryListViewModel.swift in Sources */,
10831091
B8CE1CAB26FD4193004AD5D5 /* DisabledCommandGroupButton.swift in Sources */,
10841092
B85D1A9D26FA8EA50053FF3C /* SnippetsLibraryListSectionView.swift in Sources */,

SnippetsLibrary.xcodeproj/xcshareddata/xcschemes/SnippetsLibrary.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
</Testables>
5252
</TestAction>
5353
<LaunchAction
54-
buildConfiguration = "Release"
54+
buildConfiguration = "Debug"
5555
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
5656
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
5757
launchStyle = "0"

SnippetsLibrary.xcodeproj/xcuserdata/krzysztoflowiec.xcuserdatad/xcschemes/xcschememanagement.plist

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
<key>SnippetsLibraryWidgetExtension.xcscheme_^#shared#^_</key>
5555
<dict>
5656
<key>orderHint</key>
57-
<integer>23</integer>
57+
<integer>1</integer>
5858
</dict>
5959
</dict>
6060
<key>SuppressBuildableAutocreation</key>
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// AppAlert.swift
3+
// SnippetsLibrary
4+
//
5+
// Created by Krzysztof Łowiec on 12/10/2021.
6+
//
7+
8+
import Foundation
9+
10+
enum AppAlert: Identifiable {
11+
case snippetDownload
12+
13+
var id: Int {
14+
switch self {
15+
case .snippetDownload: return 0
16+
}
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// String+Extensions.swift
3+
// SnippetsLibrary
4+
//
5+
// Created by Krzysztof Łowiec on 12/10/2021.
6+
//
7+
8+
import Foundation
9+
10+
extension String {
11+
12+
func numberOfLines() -> Int {
13+
return numberOfOccurrencesOf(string: "\n") + 1
14+
}
15+
16+
func numberOfOccurrencesOf(string: String) -> Int {
17+
return components(separatedBy: string).count - 1
18+
}
19+
20+
}

SnippetsLibrary/Models/Snippet.swift

+8-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct Snippet: Codable, Identifiable, Hashable {
2121
var completion: String
2222
var platform: SnippetPlatform
2323
var availability: SnippetAvailability
24+
var tags: [String]?
2425

2526
// MARK: - Computed Properties
2627

@@ -35,7 +36,7 @@ struct Snippet: Codable, Identifiable, Hashable {
3536
// MARK: - CodingKeys
3637

3738
enum CodingKeys: String, CodingKey {
38-
case id, title, summary, content, author, completion, platform, availability
39+
case id, title, summary, content, author, completion, platform, availability, tags
3940
}
4041

4142
// MARK: - Initialization
@@ -70,7 +71,8 @@ struct Snippet: Codable, Identifiable, Hashable {
7071
author: String,
7172
completion: String,
7273
platform: SnippetPlatform,
73-
availability: SnippetAvailability
74+
availability: SnippetAvailability,
75+
tags: [String] = []
7476
) {
7577
self.id = id
7678
self.title = title
@@ -80,6 +82,7 @@ struct Snippet: Codable, Identifiable, Hashable {
8082
self.completion = completion
8183
self.platform = platform
8284
self.availability = availability
85+
self.tags = tags
8386
}
8487

8588
init(from snippetPlist: SnippetPlist) {
@@ -91,6 +94,7 @@ struct Snippet: Codable, Identifiable, Hashable {
9194
completion = snippetPlist.completion
9295
platform = SnippetPlatform.allCases.first(where: { $0.rawValue == snippetPlist.platform }) ?? SnippetPlatform.all
9396
availability = SnippetAvailability.allCases.first(where: { $0.string == snippetPlist.availability.first }) ?? SnippetAvailability.allScopes
97+
tags = []
9498
}
9599

96100
init(from decoder: Decoder) throws {
@@ -107,6 +111,7 @@ struct Snippet: Codable, Identifiable, Hashable {
107111

108112
let availabilityName = try values.decode([String].self, forKey: .availability)
109113
availability = SnippetAvailability.allCases.first { $0.string == availabilityName.first } ?? .allScopes
114+
tags = try? values.decode([String].self, forKey: .tags)
110115
}
111116

112117
// MARK: - Methods
@@ -121,6 +126,7 @@ struct Snippet: Codable, Identifiable, Hashable {
121126
try container.encode(completion, forKey: .completion)
122127
try container.encode(platform.title, forKey: .platform)
123128
try container.encode(availability.title, forKey: .availability)
129+
try? container.encode(tags, forKey: .tags)
124130
}
125131

126132
}

SnippetsLibrary/Modules/SnippetsLibrary/SnippetLibraryList/SnippetsLibraryListView.swift

+11-5
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,26 @@ struct SnippetsLibraryListView: View {
3434
} label: {
3535
Image(systemName: "line.horizontal.3.decrease.circle")
3636
.font(.system(size: 15, weight: .light))
37-
.foregroundColor(Color.primary.opacity(Layout.mediumOpacity))
37+
.foregroundColor(
38+
Color.primary
39+
.opacity(Layout.mediumOpacity)
40+
)
3841
}
3942
.buttonStyle(PlainButtonStyle())
40-
.help("Choose the filters.")
43+
.help("Choose the filters")
4144

4245
Button {
4346
viewModel.onReload()
4447
} label: {
45-
Image(systemName: "arrow.down.circle")
48+
Image(systemName: "arrow.counterclockwise.circle")
4649
.font(.system(size: 15, weight: .light))
47-
.foregroundColor(Color.primary.opacity(Layout.mediumOpacity))
50+
.foregroundColor(
51+
Color.primary
52+
.opacity(Layout.mediumOpacity)
53+
)
4854
}
4955
.buttonStyle(PlainButtonStyle())
50-
.help("Pull all changes from remote.")
56+
.help("Pull all changes from remote")
5157
.padding(.trailing, Layout.smallPadding)
5258
}
5359
.padding(.top, Layout.largePadding)

SnippetsLibrary/Modules/SnippetsLibrary/SnippetsLibraryPreview/SnippetsLibraryPreviewView.swift

+34-27
Original file line numberDiff line numberDiff line change
@@ -14,43 +14,50 @@ struct SnippetsLibraryPreviewView: View {
1414
@Binding internal var snippets: [Snippet]
1515
@Binding internal var selectedSnippetId: SnippetId?
1616
@Binding internal var activeSheet: AppSheet?
17+
@Binding internal var appAlert: AppAlert?
1718

1819
private(set) var onTap: (_ snippet: Snippet) -> Void
1920

2021
// MARK: - Views
2122

2223
var body: some View {
23-
VStack {
24-
VStack {
25-
Spacer()
26-
27-
Text("Tap the snippet on the left to preview")
28-
.font(.system(size: 17.0))
29-
.foregroundColor(
30-
Color.primary
31-
.opacity(Layout.mediumOpacity)
32-
)
24+
VStack(spacing: .zero) {
25+
Spacer()
26+
.makeVisible(
27+
selectedSnippetId == nil,
28+
removed: true
29+
)
30+
31+
Text("Tap the snippet on the left to preview")
32+
.font(.system(size: 17.0))
33+
.foregroundColor(
34+
Color.primary
35+
.opacity(Layout.mediumOpacity)
36+
)
37+
.makeVisible(
38+
selectedSnippetId == nil,
39+
removed: true
40+
)
41+
42+
SnippetFileCardView(
43+
viewModel: SnippetFileCardViewModel(
44+
snippet: snippets.first(where: { $0.id == selectedSnippetId }),
45+
state: .preview,
46+
activeSheet: $activeSheet,
47+
appAlert: $appAlert
48+
)
49+
)
50+
.padding()
51+
.onTapGesture {
52+
guard let snippet = snippets.first(where: { $0.id == selectedSnippetId }) else { return }
53+
activeSheet = .snippetDetails(snippet, .edit)
54+
onTap(snippet)
3355
}
3456
.makeVisible(
35-
selectedSnippetId == nil,
57+
selectedSnippetId != nil,
3658
removed: true
3759
)
38-
39-
List(snippets.filter({ $0.id == selectedSnippetId })) {
40-
SnippetFileCardView(
41-
viewModel: SnippetFileCardViewModel(
42-
snippet: $0,
43-
state: .preview
44-
)
45-
)
46-
.onTapGesture {
47-
guard let snippet = snippets.first(where: { $0.id == selectedSnippetId }) else { return }
48-
activeSheet = .snippetDetails(snippet, .edit)
49-
onTap(snippet)
50-
}
51-
}
52-
.makeVisible(selectedSnippetId != nil)
53-
60+
5461
Spacer()
5562
}
5663
.frame(minWidth: Layout.defaultWindowSize.width * 0.65)

SnippetsLibrary/Modules/SnippetsLibrary/SnippetsLibraryView.swift

+13-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
//
77

88
import SwiftUI
9-
import Combine
109

1110
struct SnippetsLibraryView: View {
1211

@@ -15,6 +14,7 @@ struct SnippetsLibraryView: View {
1514
@ObservedObject private(set) var viewModel: SnippetsLibraryViewModel
1615

1716
@Binding internal var activeSheet: AppSheet?
17+
@State private var appAlert: AppAlert? = nil
1818

1919
// MARK: - Views
2020

@@ -34,7 +34,8 @@ struct SnippetsLibraryView: View {
3434
SnippetsLibraryPreviewView(
3535
snippets: $viewModel.snippets,
3636
selectedSnippetId: $viewModel.selectedSnippetId,
37-
activeSheet: $activeSheet
37+
activeSheet: $activeSheet,
38+
appAlert: $appAlert
3839
) {
3940
viewModel.saveSnippetToRecentSnippets($0)
4041
}
@@ -65,6 +66,16 @@ struct SnippetsLibraryView: View {
6566
SnippetsUploadView(viewModel: SnippetsUploadViewModel(snippets: viewModel.snippets))
6667
}
6768
}
69+
.alert(item: $appAlert) {
70+
switch $0 {
71+
case .snippetDownload:
72+
return Alert(
73+
title: Text("Unexpected error"),
74+
message: Text("Unable to download the snippet. Please try again later."),
75+
dismissButton: .cancel()
76+
)
77+
}
78+
}
6879
.makeDisplayed(
6980
with: $viewModel.shouldShowErrorAlert,
7081
imageName: "network",

SnippetsLibrary/Supporting Files/Enums/PlistCodingKeys.swift

+1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ enum PlistCodingKeys: String, CodingKey {
1919
case userSnippet = "IDECodeSnippetUserSnippet"
2020
case version = "IDECodeSnippetVersion"
2121
case author = "IDECodeSnippetAuthor"
22+
case tags = "IDECodeSnippetTags"
2223
}

0 commit comments

Comments
 (0)