Skip to content

Commit f5c9628

Browse files
authored
Merge pull request #21 from SNQ-2001/main
Include URL in library information
2 parents 229db86 + 567f415 commit f5c9628

10 files changed

+116
-7
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ import LicenseList
5151
// in ViewController
5252
let vc = LicenseListViewController()
5353
vc.title = "LICENSE"
54+
55+
// If you want to anchor link of the repository
56+
vc.licenseListViewStyle = .withRepositoryAnchorLink
57+
5458
navigationController?.pushViewController(vc, animated: true)
5559
```
5660

@@ -63,6 +67,8 @@ struct ContentView: View {
6367
var body: some View {
6468
NavigationView {
6569
LicenseListView()
70+
// If you want to anchor link of the repository
71+
.licenseListViewStyle(.withRepositoryAnchorLink)
6672
.navigationTitle("LICENSE")
6773
}
6874
}

Sources/LicenseList/LegacyLicenseView.swift

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import SwiftUI
1010
public struct LegacyLicenseView: View {
1111
@State private var lines = [[LegacyLicenseSentence]]()
1212

13+
@Environment(\.licenseListViewStyle) private var licenseListViewStyle: LicenseListViewStyle
14+
1315
private let library: Library
1416

1517
public init(library: Library) {
@@ -52,6 +54,11 @@ public struct LegacyLicenseView: View {
5254
lines = resolve(library.licenseBody)
5355
}
5456
.navigationBarTitleInlineIfPossible(library.name)
57+
._licenseListViewStyle(licenseListViewStyle) {
58+
if let url = library.url {
59+
UIApplication.shared.open(url)
60+
}
61+
}
5562
}
5663

5764
private func resolve(_ inputText: String) -> [[LegacyLicenseSentence]] {

Sources/LicenseList/Library.swift

+9-3
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ import Foundation
1010
public struct Library: Identifiable, Hashable {
1111
public let id: UUID = .init()
1212
public let name: String
13+
public let url: URL?
1314
public let licenseBody: String
1415

15-
public init(name: String, licenseBody: String) {
16+
public init(name: String, url: String, licenseBody: String) {
1617
self.name = name
18+
self.url = URL(string: url)
1719
self.licenseBody = licenseBody
1820
}
1921
}
@@ -27,8 +29,12 @@ extension Library {
2729
return []
2830
}
2931
return (dict["libraries"] as? [[String: Any]])?.compactMap({ info -> Library? in
30-
guard let name = info["name"] as? String, let body = info["licenseBody"] as? String else { return nil }
31-
return Library(name: name, licenseBody: body)
32+
guard let name = info["name"] as? String,
33+
let url = info["url"] as? String,
34+
let body = info["licenseBody"] as? String else {
35+
return nil
36+
}
37+
return Library(name: name, url: url, licenseBody: body)
3238
}) ?? []
3339
}
3440
}

Sources/LicenseList/LicenseListView.swift

+12-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import UIKit
99
import SwiftUI
1010

1111
public struct LicenseListView: View {
12+
@Environment(\.licenseListViewStyle) private var licenseListViewStyle: LicenseListViewStyle
13+
1214
let libraries: [Library]
1315
let useUINavigationController: Bool
1416
let navigationHandler: ((Library) -> Void)?
@@ -28,10 +30,11 @@ public struct LicenseListView: View {
2830
}
2931
libraries = (dict["libraries"] as? [[String: Any]])?.compactMap({ info -> Library? in
3032
guard let name = info["name"] as? String,
33+
let url = info["url"] as? String,
3134
let body = info["licenseBody"] as? String else {
3235
return nil
3336
}
34-
return Library(name: name, licenseBody: body)
37+
return Library(name: name, url: url, licenseBody: body)
3538
}) ?? []
3639
}
3740

@@ -62,11 +65,17 @@ public struct LicenseListView: View {
6265
@ViewBuilder
6366
func libraryNavigationLink(_ library: Library) -> some View {
6467
if #available(iOS 15, *) {
65-
NavigationLink(destination: LicenseView(library: library)) {
68+
NavigationLink {
69+
LicenseView(library: library)
70+
.licenseListViewStyle(licenseListViewStyle)
71+
} label: {
6672
Text(library.name)
6773
}
6874
} else {
69-
NavigationLink(destination: LegacyLicenseView(library: library)) {
75+
NavigationLink {
76+
LegacyLicenseView(library: library)
77+
.licenseListViewStyle(licenseListViewStyle)
78+
} label: {
7079
Text(library.name)
7180
}
7281
}

Sources/LicenseList/LicenseListViewController.swift

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import SwiftUI
1111
public class LicenseListViewController: UIViewController {
1212
let fileURL: URL
1313

14+
public var licenseListViewStyle: LicenseListViewStyle = .plain
15+
1416
public init(fileURL: URL) {
1517
self.fileURL = fileURL
1618
super.init(nibName: nil, bundle: nil)
@@ -46,8 +48,10 @@ public class LicenseListViewController: UIViewController {
4648
let hostingController = UIHostingController(rootView: Group {
4749
if #available(iOS 15, *) {
4850
LicenseView(library: library)
51+
.licenseListViewStyle(licenseListViewStyle)
4952
} else {
5053
LegacyLicenseView(library: library)
54+
.licenseListViewStyle(licenseListViewStyle)
5155
}
5256
})
5357
hostingController.title = library.name
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
// LicenseListViewStyle.swift
3+
//
4+
//
5+
// Created by 宮本大新 on 2023/11/16.
6+
//
7+
8+
import SwiftUI
9+
10+
public enum LicenseListViewStyle {
11+
case plain
12+
case withRepositoryAnchorLink
13+
}
14+
15+
struct LicenseListViewStyleEnvironmentKey: EnvironmentKey {
16+
typealias Value = LicenseListViewStyle
17+
18+
static var defaultValue: LicenseListViewStyle = .plain
19+
}
20+
21+
extension EnvironmentValues {
22+
var licenseListViewStyle: LicenseListViewStyle {
23+
get { self[LicenseListViewStyleEnvironmentKey.self] }
24+
set { self[LicenseListViewStyleEnvironmentKey.self] = newValue }
25+
}
26+
}

Sources/LicenseList/LicenseView.swift

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import SwiftUI
1111
public struct LicenseView: View {
1212
@State private var attributedLicenseBody = AttributedString(stringLiteral: "")
1313

14+
@Environment(\.openURL) private var openURL: OpenURLAction
15+
@Environment(\.licenseListViewStyle) private var licenseListViewStyle: LicenseListViewStyle
16+
1417
private let library: Library
1518

1619
public init(library: Library) {
@@ -28,6 +31,11 @@ public struct LicenseView: View {
2831
}
2932
}
3033
.navigationBarTitle(library.name)
34+
._licenseListViewStyle(licenseListViewStyle) {
35+
if let url = library.url {
36+
openURL(url)
37+
}
38+
}
3139
}
3240

3341
private func attribute(_ inputText: String) -> AttributedString {

Sources/LicenseList/View+Extensions.swift

+37
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,41 @@ extension View {
2727
}
2828
}
2929
}
30+
31+
func navigationBarRepositoryAnchorLink(action: @escaping () -> Void) -> some View {
32+
Group {
33+
if #available(iOS 14, *) {
34+
self.toolbar {
35+
ToolbarItem(placement: .topBarTrailing) {
36+
Button {
37+
action()
38+
} label: {
39+
Image(systemName: "link")
40+
}
41+
}
42+
}
43+
} else {
44+
self.navigationBarItems(trailing: Button {
45+
action()
46+
} label: {
47+
Image(systemName: "link")
48+
})
49+
}
50+
}
51+
}
52+
53+
func _licenseListViewStyle(_ style: LicenseListViewStyle, action: @escaping () -> Void) -> some View {
54+
Group {
55+
switch style {
56+
case .plain:
57+
self
58+
case .withRepositoryAnchorLink:
59+
self.navigationBarRepositoryAnchorLinkIfPossible(action: action)
60+
}
61+
}
62+
}
63+
64+
public func licenseListViewStyle(_ style: LicenseListViewStyle) -> some View {
65+
self.environment(\.licenseListViewStyle, style)
66+
}
3067
}

Sources/SourcePackagesParser/Library.swift

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ import Foundation
99

1010
struct Library: Hashable {
1111
let name: String
12+
let url: String
1213
let licenseBody: String
1314
}

Sources/SourcePackagesParser/SourcePackagesParser.swift

+6-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ final class SourcePackagesParser {
3636
guard let licenseBody = extractLicenseBody(directoryURL) else {
3737
return nil
3838
}
39-
return Library(name: dependency.packageRef.name, licenseBody: licenseBody)
39+
return Library(
40+
name: dependency.packageRef.name,
41+
url: dependency.packageRef.location,
42+
licenseBody: licenseBody
43+
)
4044
}
4145
.sorted { $0.name.lowercased() < $1.name.lowercased() }
4246

@@ -84,6 +88,7 @@ final class SourcePackagesParser {
8488
let array: [[String: Any]] = libraries.map { library in
8589
return [
8690
"name": library.name,
91+
"url": library.url,
8792
"licenseBody": library.licenseBody
8893
]
8994
}

0 commit comments

Comments
 (0)