a masterpiece ong
Some checks are pending
Build and Release / Build IPA (push) Waiting to run
Build and Release / Build Mac Catalyst (push) Waiting to run

This commit is contained in:
Francesco 2025-05-26 20:09:52 +02:00
parent 95c1a29c18
commit 967791878a
3 changed files with 182 additions and 0 deletions

View file

@ -0,0 +1,175 @@
//
// SettingsViewAbout.swift
// Sulfur
//
// Created by Francesco on 26/05/25.
//
import SwiftUI
import Kingfisher
struct SettingsViewAbout: View {
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "ALPHA"
var body: some View {
Form {
Section(footer: Text("Sora/Sulfur will always remain free with no ADs!")) {
HStack {
KFImage(URL(string: "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/dev/Sora/Assets.xcassets/AppIcons/AppIcon_Default.appiconset/darkmode.png"))
.placeholder {
ProgressView()
}
.resizable()
.frame(width: 100, height: 100)
.cornerRadius(20)
.shadow(radius: 5)
VStack(spacing: 8) {
Text("Sora")
.font(.title)
.bold()
Text("Version \(version)")
.font(.subheadline)
.foregroundColor(.secondary)
}
}
.listRowInsets(EdgeInsets())
.padding()
}
Section("Main Developer") {
Button(action: {
if let url = URL(string: "https://github.com/cranci1") {
UIApplication.shared.open(url)
}
}) {
HStack {
KFImage(URL(string: "https://avatars.githubusercontent.com/u/100066266?v=4"))
.placeholder {
ProgressView()
}
.resizable()
.frame(width: 40, height: 40)
.clipShape(Circle())
VStack(alignment: .leading) {
Text("cranci1")
.font(.headline)
.foregroundColor(.indigo)
Text("me frfr")
.font(.subheadline)
.foregroundColor(.secondary)
}
Spacer()
Image(systemName: "safari")
.foregroundColor(.indigo)
}
}
}
Section("Contributors") {
ContributorsView()
}
}
.navigationTitle("About")
}
}
struct ContributorsView: View {
@State private var contributors: [Contributor] = []
@State private var isLoading = true
@State private var error: Error?
var body: some View {
Group {
if isLoading {
HStack {
Spacer()
ProgressView()
Spacer()
}
} else if error != nil {
Text("Failed to load contributors")
.foregroundColor(.secondary)
} else {
ForEach(filteredContributors) { contributor in
ContributorView(contributor: contributor)
}
}
}
.onAppear {
loadContributors()
}
}
private var filteredContributors: [Contributor] {
contributors.filter { contributor in
!["cranci1", "code-factor"].contains(contributor.login.lowercased())
}
}
private func loadContributors() {
let url = URL(string: "https://api.github.com/repos/cranci1/Sora/contributors")!
URLSession.shared.dataTask(with: url) { data, response, error in
DispatchQueue.main.async {
isLoading = false
if let error = error {
self.error = error
return
}
if let data = data {
do {
self.contributors = try JSONDecoder().decode([Contributor].self, from: data)
} catch {
self.error = error
}
}
}
}.resume()
}
}
struct ContributorView: View {
let contributor: Contributor
var body: some View {
Button(action: {
if let url = URL(string: "https://github.com/\(contributor.login)") {
UIApplication.shared.open(url)
}
}) {
HStack {
KFImage(URL(string: contributor.avatarUrl))
.placeholder {
ProgressView()
}
.resizable()
.frame(width: 40, height: 40)
.clipShape(Circle())
Text(contributor.login)
.font(.headline)
.foregroundColor(.accentColor)
Spacer()
Image(systemName: "safari")
.foregroundColor(.accentColor)
}
}
}
}
struct Contributor: Identifiable, Decodable {
let id: Int
let login: String
let avatarUrl: String
enum CodingKeys: String, CodingKey {
case id
case login
case avatarUrl = "avatar_url"
}
}

View file

@ -41,6 +41,9 @@ struct SettingsView: View {
}
Section(header: Text("Info")) {
NavigationLink(destination: SettingsViewAbout()) {
Text("About Sora")
}
Button(action: {
if let url = URL(string: "https://github.com/cranci1/Sora") {
UIApplication.shared.open(url)

View file

@ -40,6 +40,7 @@
136BBE802DB1038000906B5E /* Notification+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136BBE7F2DB1038000906B5E /* Notification+Name.swift */; };
138AA1B82D2D66FD0021F9DF /* EpisodeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138AA1B62D2D66FD0021F9DF /* EpisodeCell.swift */; };
138AA1B92D2D66FD0021F9DF /* CircularProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138AA1B72D2D66FD0021F9DF /* CircularProgressBar.swift */; };
1398FB3F2DE4E161004D3F5F /* SettingsViewAbout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1398FB3E2DE4E161004D3F5F /* SettingsViewAbout.swift */; };
139935662D468C450065CEFF /* ModuleManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139935652D468C450065CEFF /* ModuleManager.swift */; };
1399FAD42D3AB38C00E97C31 /* SettingsViewLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1399FAD32D3AB38C00E97C31 /* SettingsViewLogger.swift */; };
1399FAD62D3AB3DB00E97C31 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1399FAD52D3AB3DB00E97C31 /* Logger.swift */; };
@ -118,6 +119,7 @@
136BBE7F2DB1038000906B5E /* Notification+Name.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+Name.swift"; sourceTree = "<group>"; };
138AA1B62D2D66FD0021F9DF /* EpisodeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EpisodeCell.swift; sourceTree = "<group>"; };
138AA1B72D2D66FD0021F9DF /* CircularProgressBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircularProgressBar.swift; sourceTree = "<group>"; };
1398FB3E2DE4E161004D3F5F /* SettingsViewAbout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewAbout.swift; sourceTree = "<group>"; };
139935652D468C450065CEFF /* ModuleManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleManager.swift; sourceTree = "<group>"; };
1399FAD32D3AB38C00E97C31 /* SettingsViewLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewLogger.swift; sourceTree = "<group>"; };
1399FAD52D3AB3DB00E97C31 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
@ -287,6 +289,7 @@
130C6BF92D53AB1F00DC1432 /* SettingsViewData.swift */,
13DB46912D900BCE008CBC03 /* SettingsViewTrackers.swift */,
72443C7E2DC8038300A61321 /* SettingsViewDownloads.swift */,
1398FB3E2DE4E161004D3F5F /* SettingsViewAbout.swift */,
);
path = SettingsSubViews;
sourceTree = "<group>";
@ -652,6 +655,7 @@
13E62FC22DABC5830007E259 /* Trakt-Login.swift in Sources */,
133F55BB2D33B55100E08EEA /* LibraryManager.swift in Sources */,
13E62FC42DABC58C0007E259 /* Trakt-Token.swift in Sources */,
1398FB3F2DE4E161004D3F5F /* SettingsViewAbout.swift in Sources */,
133D7C8E2D2BE2640075467E /* LibraryView.swift in Sources */,
13E62FC72DABFE900007E259 /* TraktPushUpdates.swift in Sources */,
133D7C6E2D2BE2500075467E /* SoraApp.swift in Sources */,