Merge branch 'fabianthdev/feature/SwiftUI' into naturecodevoid/swiftui-improvements

Signed-off-by: naturecodevoid <44983869+naturecodevoid@users.noreply.github.com>
This commit is contained in:
naturecodevoid
2023-02-19 09:56:21 -08:00
committed by GitHub
14 changed files with 329 additions and 87 deletions

View File

@@ -35,6 +35,7 @@
1F1295812989B51F0048FCB9 /* ExpandableText in Frameworks */ = {isa = PBXBuildFile; productRef = 1F1295802989B51F0048FCB9 /* ExpandableText */; }; 1F1295812989B51F0048FCB9 /* ExpandableText in Frameworks */ = {isa = PBXBuildFile; productRef = 1F1295802989B51F0048FCB9 /* ExpandableText */; };
1F180F92298E7A1B00D1C98B /* StoreApp+Trusted.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F180F91298E7A1B00D1C98B /* StoreApp+Trusted.swift */; }; 1F180F92298E7A1B00D1C98B /* StoreApp+Trusted.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F180F91298E7A1B00D1C98B /* StoreApp+Trusted.swift */; };
1F180F94298E7A2500D1C98B /* Source+Trusted.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F180F93298E7A2500D1C98B /* Source+Trusted.swift */; }; 1F180F94298E7A2500D1C98B /* Source+Trusted.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F180F93298E7A2500D1C98B /* Source+Trusted.swift */; };
1F1D669E29A234CE0095BFCD /* WriteAppReviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1D669D29A234CE0095BFCD /* WriteAppReviewView.swift */; };
1F2EF787297C4D40002FD839 /* LicensesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F2EF786297C4D40002FD839 /* LicensesView.swift */; }; 1F2EF787297C4D40002FD839 /* LicensesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F2EF786297C4D40002FD839 /* LicensesView.swift */; };
1F44634529744E570070E514 /* HintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F44634429744E570070E514 /* HintView.swift */; }; 1F44634529744E570070E514 /* HintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F44634429744E570070E514 /* HintView.swift */; };
1F545E83298D79E400589F68 /* ErrorLogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F545E82298D79E400589F68 /* ErrorLogView.swift */; }; 1F545E83298D79E400589F68 /* ErrorLogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F545E82298D79E400589F68 /* ErrorLogView.swift */; };
@@ -594,6 +595,7 @@
1F0DD8442936B3FE007608A4 /* FilledButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilledButtonStyle.swift; sourceTree = "<group>"; }; 1F0DD8442936B3FE007608A4 /* FilledButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilledButtonStyle.swift; sourceTree = "<group>"; };
1F180F91298E7A1B00D1C98B /* StoreApp+Trusted.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StoreApp+Trusted.swift"; sourceTree = "<group>"; }; 1F180F91298E7A1B00D1C98B /* StoreApp+Trusted.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StoreApp+Trusted.swift"; sourceTree = "<group>"; };
1F180F93298E7A2500D1C98B /* Source+Trusted.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Source+Trusted.swift"; sourceTree = "<group>"; }; 1F180F93298E7A2500D1C98B /* Source+Trusted.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Source+Trusted.swift"; sourceTree = "<group>"; };
1F1D669D29A234CE0095BFCD /* WriteAppReviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteAppReviewView.swift; sourceTree = "<group>"; };
1F2EF786297C4D40002FD839 /* LicensesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LicensesView.swift; sourceTree = "<group>"; }; 1F2EF786297C4D40002FD839 /* LicensesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LicensesView.swift; sourceTree = "<group>"; };
1F44634429744E570070E514 /* HintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HintView.swift; sourceTree = "<group>"; }; 1F44634429744E570070E514 /* HintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HintView.swift; sourceTree = "<group>"; };
1F545E82298D79E400589F68 /* ErrorLogView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorLogView.swift; sourceTree = "<group>"; }; 1F545E82298D79E400589F68 /* ErrorLogView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorLogView.swift; sourceTree = "<group>"; };
@@ -1193,6 +1195,7 @@
1F0DD8202933B749007608A4 /* AppPermissionsGrid.swift */, 1F0DD8202933B749007608A4 /* AppPermissionsGrid.swift */,
1F07F56A2955F11500F7BE95 /* AppScreenshotsPreview.swift */, 1F07F56A2955F11500F7BE95 /* AppScreenshotsPreview.swift */,
1FFEF103298552DB0098374C /* AppVersionHistoryView.swift */, 1FFEF103298552DB0098374C /* AppVersionHistoryView.swift */,
1F1D669D29A234CE0095BFCD /* WriteAppReviewView.swift */,
); );
path = "App Detail"; path = "App Detail";
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2889,6 +2892,7 @@
BF9ABA4B22DD1380008935CF /* NavigationBar.swift in Sources */, BF9ABA4B22DD1380008935CF /* NavigationBar.swift in Sources */,
BF6C8FAC242935ED00125131 /* NSAttributedString+Markdown.m in Sources */, BF6C8FAC242935ED00125131 /* NSAttributedString+Markdown.m in Sources */,
BFF00D322501BDA100746320 /* BackgroundRefreshAppsOperation.swift in Sources */, BFF00D322501BDA100746320 /* BackgroundRefreshAppsOperation.swift in Sources */,
1F1D669E29A234CE0095BFCD /* WriteAppReviewView.swift in Sources */,
1F66F5BC2938F03700A910CA /* Modifiers.swift in Sources */, 1F66F5BC2938F03700A910CA /* Modifiers.swift in Sources */,
99DE640329A1624500B920BF /* View+SideStore.swift in Sources */, 99DE640329A1624500B920BF /* View+SideStore.swift in Sources */,
1FA5A6CA298E8B2F007BA946 /* RefreshAttemptsView.swift in Sources */, 1FA5A6CA298E8B2F007BA946 /* RefreshAttemptsView.swift in Sources */,

View File

@@ -55,3 +55,26 @@ extension AppIconView: Equatable {
lhs.iconUrl == rhs.iconUrl && lhs.cornerRadius == rhs.cornerRadius lhs.iconUrl == rhs.iconUrl && lhs.cornerRadius == rhs.cornerRadius
} }
} }
import AltStoreCore
struct AppIconView_Previews: PreviewProvider {
static let context = DatabaseManager.shared.viewContext
static let app = StoreApp.makeAltStoreApp(in: context)
static var previews: some View {
HStack {
AppIconView(iconUrl: app.iconURL)
VStack(alignment: .leading) {
Text(app.name)
.bold()
Text(app.developerName)
.font(.callout)
.foregroundColor(.secondary)
}
}
}
}

View File

@@ -75,7 +75,7 @@ struct AppPillButton: View {
} }
func refreshApp(_ installedApp: InstalledApp) { func refreshApp(_ installedApp: InstalledApp) {
AppManager.shared.refresh([installedApp], presentingViewController: nil)
} }
func installApp(_ storeApp: StoreApp) { func installApp(_ storeApp: StoreApp) {
@@ -100,8 +100,45 @@ struct AppPillButton: View {
} }
} }
//struct AppPillButton_Previews: PreviewProvider { struct AppPillButton_Previews: PreviewProvider {
// static var previews: some View {
// AppPillButton() static let context = DatabaseManager.shared.viewContext
// } static let app = StoreApp.makeAltStoreApp(in: context)
//} static let installedApp = InstalledApp.fetchAltStore(in: context)
static var previews: some View {
VStack {
self.preview(for: app)
self.preview(for: installedApp!)
self.preview(for: installedApp!, showRemainingDays: true)
}
.padding()
}
@ViewBuilder
static func preview(for app: AppProtocol, showRemainingDays: Bool = false) -> some View {
HintView(backgroundColor: Color(UIColor.secondarySystemBackground)) {
HStack {
AppIconView(iconUrl: self.app.iconURL)
VStack(alignment: .leading) {
Text(app is StoreApp ? "Store App" : "Installed App")
.bold()
Text(
app is StoreApp ?
"Can be installed" :
showRemainingDays ? "Can be refreshed" : "Can be opened"
)
.font(.callout)
.foregroundColor(.secondary)
}
Spacer()
AppPillButton(app: app, showRemainingDays: showRemainingDays)
}
}
}
}

View File

@@ -41,9 +41,15 @@ extension AppScreenshot {
} }
import AltStoreCore
struct AppScreenshot_Previews: PreviewProvider { struct AppScreenshot_Previews: PreviewProvider {
static let context = DatabaseManager.shared.viewContext
static let app = StoreApp.makeAltStoreApp(in: context)
static var previews: some View { static var previews: some View {
AppScreenshot(url: URL(string: "https://apps.sidestore.io/apps/sidestore/v0.1.1/browse-dark.png")!) AppScreenshot(url: app.screenshotURLs[0])
.padding()
} }
} }

View File

@@ -14,6 +14,16 @@ struct ModalNavigationLink<Label: View, Modal: View>: View {
@State var isPresentingModal: Bool = false @State var isPresentingModal: Bool = false
init(@ViewBuilder modal: @escaping () -> Modal, @ViewBuilder label: @escaping () -> Label) {
self.modal = modal
self.label = label
}
init(_ title: String, @ViewBuilder modal: @escaping () -> Modal) where Label == Text {
self.modal = modal
self.label = { Text(title) }
}
var body: some View { var body: some View {
SwiftUI.Button { SwiftUI.Button {
self.isPresentingModal = true self.isPresentingModal = true
@@ -26,8 +36,10 @@ struct ModalNavigationLink<Label: View, Modal: View>: View {
} }
} }
//struct ModalNavigationLink_Previews: PreviewProvider { struct ModalNavigationLink_Previews: PreviewProvider {
// static var previews: some View { static var previews: some View {
// ModalNavigationLink() ModalNavigationLink("Present Modal") {
// } Text("Modal")
//} }
}
}

View File

@@ -10,7 +10,7 @@ import SwiftUI
extension View { extension View {
@ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View { @ViewBuilder func `if`<Content: View>(_ condition: Bool, @ViewBuilder transform: (Self) -> Content) -> some View {
if condition { if condition {
transform(self) transform(self)
} else { } else {

View File

@@ -36,6 +36,11 @@ struct AppDetailView: View {
max(CGFloat.zero, min(maxContentCornerRadius, maxContentCornerRadius * (1 - self.scrollOffset / self.headerViewHeight))) max(CGFloat.zero, min(maxContentCornerRadius, maxContentCornerRadius * (1 - self.scrollOffset / self.headerViewHeight)))
} }
var canRateApp: Bool {
self.storeApp.installedApp != nil
}
var body: some View { var body: some View {
ObservableScrollView(scrollOffset: $scrollOffset) { proxy in ObservableScrollView(scrollOffset: $scrollOffset) { proxy in
LazyVStack { LazyVStack {
@@ -86,7 +91,7 @@ struct AppDetailView: View {
} }
var contentView: some View { var contentView: some View {
VStack(alignment: .leading) { VStack(alignment: .leading, spacing: 24) {
VStack(alignment: .leading, spacing: 32) { VStack(alignment: .leading, spacing: 32) {
if storeApp.isFromOfficialSource { if storeApp.isFromOfficialSource {
officialAppBadge officialAppBadge
@@ -145,7 +150,7 @@ struct AppDetailView: View {
} }
VStack(spacing: 16) { VStack(spacing: 24) {
Divider() Divider()
currentVersionView currentVersionView
@@ -179,23 +184,29 @@ struct AppDetailView: View {
} }
var officialAppBadge: some View { var officialAppBadge: some View {
HStack { HintView(backgroundColor: Color(UIColor.secondarySystemBackground)) {
Spacer() HStack {
Image(systemSymbol: .checkmarkSealFill) Spacer()
Text(L10n.AppDetailView.Badge.official) Image(systemSymbol: .checkmarkSealFill)
Spacer() Text(L10n.AppDetailView.Badge.official)
Spacer()
}
.foregroundColor(.accentColor)
} }
.foregroundColor(.accentColor) .padding(.horizontal)
} }
var trustedAppBadge: some View { var trustedAppBadge: some View {
HStack { HintView(backgroundColor: Color(UIColor.secondarySystemBackground)) {
Spacer() HStack {
Image(systemSymbol: .shieldLefthalfFill) Spacer()
Text(L10n.AppDetailView.Badge.trusted) Image(systemSymbol: .shieldLefthalfFill)
Spacer() Text(L10n.AppDetailView.Badge.trusted)
Spacer()
}
.foregroundColor(.accentColor)
} }
.foregroundColor(.accentColor) .padding(.horizontal)
} }
var currentVersionView: some View { var currentVersionView: some View {
@@ -318,7 +329,7 @@ struct AppDetailView: View {
.foregroundColor(.secondary) .foregroundColor(.secondary)
} }
RatingStars(rating: i + 1) RatingStars(rating: 5 - i)
.frame(height: 12) .frame(height: 12)
.foregroundColor(.yellow) .foregroundColor(.yellow)
} }
@@ -337,6 +348,17 @@ struct AppDetailView: View {
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.frame(height: 150) .frame(height: 150)
.padding(.horizontal, -16) .padding(.horizontal, -16)
if self.canRateApp {
ModalNavigationLink {
NavigationView {
WriteAppReviewView(storeApp: self.storeApp)
}
} label: {
Label("Write a Review", systemSymbol: .squareAndPencil)
}
.frame(maxWidth: .infinity, alignment: .leading)
}
} }
} }
@@ -353,9 +375,8 @@ struct AppDetailView: View {
} else { } else {
AppPermissionsGrid(permissions: storeApp.permissions) AppPermissionsGrid(permissions: storeApp.permissions)
} }
Spacer()
} }
.frame(maxWidth: .infinity, alignment: .leading)
} }
var informationData: [(title: String, content: String)] { var informationData: [(title: String, content: String)] {
@@ -418,3 +439,16 @@ struct AppDetailView: View {
} }
} }
} }
struct AppDetailView_Previews: PreviewProvider {
static let context = DatabaseManager.shared.viewContext
static let app = StoreApp.makeAltStoreApp(in: context)
static var previews: some View {
NavigationView {
AppDetailView(storeApp: app)
}
}
}

View File

@@ -55,8 +55,17 @@ extension AppScreenshotsPreview: Equatable {
} }
} }
//struct AppScreenshotsPreview_Previews: PreviewProvider { struct AppScreenshotsPreview_Previews: PreviewProvider {
// static var previews: some View {
// AppScreenshotsPreview() static let context = DatabaseManager.shared.viewContext
// } static let app = StoreApp.makeAltStoreApp(in: context)
//}
static var previews: some View {
Color.clear
.sheet(isPresented: .constant(true)) {
NavigationView {
AppScreenshotsPreview(urls: app.screenshotURLs)
}
}
}
}

View File

@@ -56,3 +56,16 @@ extension Int: Identifiable {
self self
} }
} }
import AltStoreCore
struct AppScreenshotsScrollView_Previews: PreviewProvider {
static let context = DatabaseManager.shared.viewContext
static let app = StoreApp.makeAltStoreApp(in: context)
static var previews: some View {
AppScreenshotsScrollView(urls: app.screenshotURLs)
}
}

View File

@@ -42,8 +42,14 @@ struct AppVersionHistoryView: View {
} }
} }
//struct AppVersionHistoryView_Previews: PreviewProvider { struct AppVersionHistoryView_Previews: PreviewProvider {
// static var previews: some View {
// AppVersionHistoryView(storeApp: ) static let context = DatabaseManager.shared.viewContext
// } static let app = StoreApp.makeAltStoreApp(in: context)
//}
static var previews: some View {
NavigationView {
AppVersionHistoryView(storeApp: app)
}
}
}

View File

@@ -0,0 +1,102 @@
//
// WriteAppReviewView.swift
// SideStore
//
// Created by Fabian Thies on 19.02.23.
// Copyright © 2023 SideStore. All rights reserved.
//
import SwiftUI
import AltStoreCore
struct WriteAppReviewView: View {
@Environment(\.dismiss) var dismiss
let storeApp: StoreApp
@State var currentRating = 0
@State var reviewText = ""
var canSendReview: Bool {
// Only allow the user to send the review if a rating has been set and
// the review text is either empty or doesn't contain only whitespaces.
self.currentRating > 0 && (
self.reviewText.isEmpty || !self.reviewText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
)
}
var body: some View {
List {
// App Information
HStack {
AppIconView(iconUrl: storeApp.iconURL, size: 50)
VStack(alignment: .leading) {
Text(storeApp.name)
.bold()
Text(storeApp.developerName)
.font(.callout)
.foregroundColor(.secondary)
}
}
// Rating
Section {
HStack {
Spacer()
ForEach(1...5) { rating in
SwiftUI.Button {
self.currentRating = rating
} label: {
Image(systemSymbol: rating > self.currentRating ? .star : .starFill)
.resizable()
.aspectRatio(contentMode: .fit)
}
.buttonStyle(PlainButtonStyle())
.frame(maxHeight: 40)
}
Spacer()
}
.foregroundColor(.yellow)
} header: {
Text("Rate the App")
}
// Review
Section {
TextEditor(text: self.$reviewText)
.frame(minHeight: 100, maxHeight: 250)
} header: {
Text("Leave a Review (optional)")
}
}
.navigationTitle("Write a Review")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
SwiftUI.Button("Cancel", action: self.dismiss)
}
ToolbarItem(placement: .confirmationAction) {
SwiftUI.Button("Send", action: self.sendReview)
.disabled(!self.canSendReview)
}
}
}
private func sendReview() {
NotificationManager.shared.showNotification(title: "Feature not Implemented")
self.dismiss()
}
}
struct WriteAppReviewView_Previews: PreviewProvider {
static let context = DatabaseManager.shared.viewContext
static let app = StoreApp.makeAltStoreApp(in: context)
static var previews: some View {
NavigationView {
WriteAppReviewView(storeApp: app)
}
}
}

View File

@@ -38,11 +38,9 @@ struct MyAppsView: View {
var viewModel = MyAppsViewModel() var viewModel = MyAppsViewModel()
// TODO: Refactor // TODO: Refactor
@State var isShowingFilePicker: Bool = false @State var isRefreshingAllApps: Bool = false
@State var selectedSideloadingIpaURL: URL? @State var selectedSideloadingIpaURL: URL?
@State var isShowingAppIDsView: Bool = false
var remainingAppIDs: Int { var remainingAppIDs: Int {
guard let team = DatabaseManager.shared.activeTeam() else { guard let team = DatabaseManager.shared.activeTeam() else {
return 0 return 0
@@ -89,11 +87,14 @@ struct MyAppsView: View {
Text(L10n.MyAppsView.active) Text(L10n.MyAppsView.active)
.font(.title2) .font(.title2)
.bold() .bold()
Spacer()
SwiftUI.Button {
} label: { Spacer()
Text(L10n.MyAppsView.refreshAll)
if !self.isRefreshingAllApps {
SwiftUI.Button(L10n.MyAppsView.refreshAll, action: self.refreshAllApps)
} else {
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
} }
} }
@@ -118,12 +119,7 @@ struct MyAppsView: View {
.foregroundColor(.secondary) .foregroundColor(.secondary)
} }
SwiftUI.Button { ModalNavigationLink(L10n.MyAppsView.viewAppIDs) {
self.isShowingAppIDsView = true
} label: {
Text(L10n.MyAppsView.viewAppIDs)
}
.sheet(isPresented: self.$isShowingAppIDsView) {
NavigationView { NavigationView {
AppIDsView() AppIDsView()
} }
@@ -137,16 +133,13 @@ struct MyAppsView: View {
.navigationTitle(L10n.MyAppsView.myApps) .navigationTitle(L10n.MyAppsView.myApps)
.toolbar { .toolbar {
ToolbarItem(placement: .navigationBarLeading) { ToolbarItem(placement: .navigationBarLeading) {
SwiftUI.Button { ModalNavigationLink {
self.isShowingFilePicker = true DocumentPicker(selectedUrl: $selectedSideloadingIpaURL, supportedTypes: sideloadFileTypes)
.ignoresSafeArea()
} label: { } label: {
Image(systemSymbol: .plus) Image(systemSymbol: .plus)
.imageScale(.large) .imageScale(.large)
} }
.sheet(isPresented: self.$isShowingFilePicker) {
DocumentPicker(selectedUrl: $selectedSideloadingIpaURL, supportedTypes: sideloadFileTypes)
.ignoresSafeArea()
}
.onChange(of: self.selectedSideloadingIpaURL) { newValue in .onChange(of: self.selectedSideloadingIpaURL) { newValue in
guard let url = newValue else { guard let url = newValue else {
return return
@@ -206,7 +199,10 @@ struct MyAppsView: View {
func refreshAllApps() { func refreshAllApps() {
let installedApps = InstalledApp.fetchAppsForRefreshingAll(in: DatabaseManager.shared.viewContext) let installedApps = InstalledApp.fetchAppsForRefreshingAll(in: DatabaseManager.shared.viewContext)
self.refresh(installedApps) { result in } self.isRefreshingAllApps = true
self.refresh(installedApps) { result in
self.isRefreshingAllApps = false
}
} }
func dismissUpdatesHint(forever: Bool) { func dismissUpdatesHint(forever: Bool) {
@@ -218,7 +214,7 @@ struct MyAppsView: View {
extension MyAppsView { extension MyAppsView {
// TODO: Convert to async // TODO: Convert to async?
func refresh(_ apps: [InstalledApp], completionHandler: @escaping ([String : Result<InstalledApp, Error>]) -> Void) { func refresh(_ apps: [InstalledApp], completionHandler: @escaping ([String : Result<InstalledApp, Error>]) -> Void) {
let group = AppManager.shared.refresh(apps, presentingViewController: nil, group: self.viewModel.refreshGroup) let group = AppManager.shared.refresh(apps, presentingViewController: nil, group: self.viewModel.refreshGroup)
@@ -248,10 +244,10 @@ extension MyAppsView {
NotificationManager.shared.showNotification(title: title, detailText: message) NotificationManager.shared.showNotification(title: title, detailText: message)
} }
}
self.viewModel.refreshGroup = nil self.viewModel.refreshGroup = nil
completionHandler(results) completionHandler(results)
}
} }
self.viewModel.refreshGroup = group self.viewModel.refreshGroup = group
@@ -429,6 +425,10 @@ extension MyAppsView {
} }
struct MyAppsView_Previews: PreviewProvider { struct MyAppsView_Previews: PreviewProvider {
static let context = DatabaseManager.shared.viewContext
static let app = StoreApp.makeAltStoreApp(in: context)
static var previews: some View { static var previews: some View {
NavigationView { NavigationView {
MyAppsView() MyAppsView()

View File

@@ -30,15 +30,13 @@ struct SettingsView: View {
var isDevModeEnabled: Bool = false var isDevModeEnabled: Bool = false
@State var isShowingConnectAppleIDView = false @State var isShowingConnectAppleIDView = false
@State var isShowingAddShortcutView = false
@State var isShowingFeedbackMailView = false
@State var isShowingResetPairingFileConfirmation = false @State var isShowingResetPairingFileConfirmation = false
@State var isShowingDevModePrompt = false @State var isShowingDevModePrompt = false
@State var isShowingDevModeMenu = false @State var isShowingDevModeMenu = false
@State var externalURLToShow: URL? @State var externalURLToShow: URL?
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown" let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown Version"
var body: some View { var body: some View {
List { List {
@@ -104,12 +102,7 @@ struct SettingsView: View {
Text(L10n.SettingsView.backgroundRefresh) Text(L10n.SettingsView.backgroundRefresh)
}) })
SwiftUI.Button { ModalNavigationLink(L10n.SettingsView.addToSiri) {
self.isShowingAddShortcutView = true
} label: {
Text(L10n.SettingsView.addToSiri)
}
.sheet(isPresented: self.$isShowingAddShortcutView) {
if let shortcut = INShortcut(intent: INInteraction.refreshAllApps().intent) { if let shortcut = INShortcut(intent: INInteraction.refreshAllApps().intent) {
SiriShortcutSetupView(shortcut: shortcut) SiriShortcutSetupView(shortcut: shortcut)
} }
@@ -169,10 +162,7 @@ struct SettingsView: View {
} }
if MailComposeView.canSendMail { if MailComposeView.canSendMail {
SwiftUI.Button("Send Feedback") { ModalNavigationLink("Send Feedback") {
self.isShowingFeedbackMailView = true
}
.sheet(isPresented: self.$isShowingFeedbackMailView) {
MailComposeView(recipients: ["support@sidestore.io"], MailComposeView(recipients: ["support@sidestore.io"],
subject: "SideStore Beta \(appVersion) Feedback") { subject: "SideStore Beta \(appVersion) Feedback") {
NotificationManager.shared.showNotification(title: "Thank you for your feedback!") NotificationManager.shared.showNotification(title: "Thank you for your feedback!")

View File

@@ -342,25 +342,31 @@ public extension StoreApp
class func makeAltStoreApp(in context: NSManagedObjectContext) -> StoreApp class func makeAltStoreApp(in context: NSManagedObjectContext) -> StoreApp
{ {
let app = StoreApp(context: context) let app = StoreApp(context: context)
app.source = Source.makeAltStoreSource(in: context)
app.name = "SideStore" app.name = "SideStore"
app.bundleIdentifier = StoreApp.altstoreAppID app.bundleIdentifier = StoreApp.altstoreAppID
app.developerName = "Side Team" app.developerName = "Side Team"
app.localizedDescription = "SideStore is an alternative App Store." app.localizedDescription = "SideStore is an alternative App Store."
app.iconURL = URL(string: "https://user-images.githubusercontent.com/705880/63392210-540c5980-c37b-11e9-968c-8742fc68ab2e.png")! app.iconURL = URL(string: "https://apps.sidestore.io/apps/sidestore/v0.1.1/icon.png")!
app.screenshotURLs = [] app.screenshotURLs = [
app.sourceIdentifier = Source.altStoreIdentifier URL(string: "https://apps.sidestore.io/apps/sidestore/v0.1.1/browse-dark.png")!,
URL(string: "https://apps.sidestore.io/apps/sidestore/v0.1.1/apps-dark.png")!,
URL(string: "https://apps.sidestore.io/apps/sidestore/v0.1.1/news-dark.png")!,
URL(string: "https://apps.sidestore.io/apps/sidestore/v0.1.1/browse-light.png")!,
URL(string: "https://apps.sidestore.io/apps/sidestore/v0.1.1/apps-light.png")!,
URL(string: "https://apps.sidestore.io/apps/sidestore/v0.1.1/news-light.png")!,
]
app.tintColor = UIColor(named: "AccentColor")
let appVersion = AppVersion.makeAppVersion(version: "0.3.0", let appVersion = AppVersion.makeAppVersion(version: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown",
date: Date(), date: Date(),
downloadURL: URL(string: "http://rileytestut.com")!, downloadURL: URL(string: "https://github.com/SideStore/SideStore/releases/download/0.1.1/SideStore.ipa")!,
size: 0, size: 0,
appBundleID: app.bundleIdentifier, appBundleID: app.bundleIdentifier,
sourceID: Source.altStoreIdentifier, sourceID: Source.altStoreIdentifier,
in: context) in: context)
app.setVersions([appVersion]) app.setVersions([appVersion])
print("makeAltStoreApp StoreApp: \(String(describing: app))")
#if BETA #if BETA
app.isBeta = true app.isBeta = true
#endif #endif