mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-14 01:03:27 +01:00
Reorganize AltStore project into UIKit and SwiftUI folders
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// ActivityView.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Fabian Thies on 19.05.23.
|
||||
// Copyright © 2023 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
|
||||
|
||||
struct ActivityView: UIViewControllerRepresentable {
|
||||
let items: [Any]
|
||||
|
||||
func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityView>) -> UIActivityViewController {
|
||||
return UIActivityViewController(activityItems: items, applicationActivities: nil)
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityView>) {}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
//
|
||||
// AppStoreProductView.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Fabian Thies on 25.02.23.
|
||||
// Copyright © 2023 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import StoreKit
|
||||
|
||||
|
||||
struct AppStoreView: UIViewControllerRepresentable {
|
||||
typealias UIViewControllerType = AppStoreProductViewController
|
||||
|
||||
var isVisible: Binding<Bool>
|
||||
let itunesItemId: Int
|
||||
|
||||
func makeUIViewController(context: Context) -> AppStoreProductViewController {
|
||||
AppStoreProductViewController(isVisible: self.isVisible, itunesId: self.itunesItemId)
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
|
||||
if self.isVisible.wrappedValue {
|
||||
uiViewController.presentStoreProduct()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class AppStoreProductViewController: UIViewController {
|
||||
|
||||
private var isVisible: Binding<Bool>
|
||||
private let itunesId: Int
|
||||
|
||||
init(isVisible: Binding<Bool>, itunesId: Int) {
|
||||
self.isVisible = isVisible
|
||||
self.itunesId = itunesId
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
}
|
||||
|
||||
func presentStoreProduct() {
|
||||
let storeProductViewController = SKStoreProductViewController()
|
||||
storeProductViewController.delegate = self
|
||||
|
||||
let parameters = [SKStoreProductParameterITunesItemIdentifier: self.itunesId]
|
||||
storeProductViewController.loadProduct(withParameters: parameters) { (success, error) -> Void in
|
||||
if let error = error {
|
||||
print("Failed to load App Store product: \(error.localizedDescription)")
|
||||
}
|
||||
guard success else {
|
||||
return
|
||||
}
|
||||
|
||||
self.present(storeProductViewController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SKStoreProductViewControllerDelegate
|
||||
|
||||
extension AppStoreProductViewController: SKStoreProductViewControllerDelegate {
|
||||
|
||||
func productViewControllerDidFinish(_ viewController: SKStoreProductViewController) {
|
||||
DispatchQueue.main.async {
|
||||
self.isVisible.wrappedValue = false
|
||||
}
|
||||
// viewController.presentingViewController?.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// DocumentPicker.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Fabian Thies on 20.12.22.
|
||||
// Copyright © 2022 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SwiftUI
|
||||
|
||||
struct DocumentPicker: UIViewControllerRepresentable {
|
||||
internal class Coordinator: NSObject {
|
||||
var parent: DocumentPicker
|
||||
|
||||
init(_ parent: DocumentPicker) {
|
||||
self.parent = parent
|
||||
}
|
||||
}
|
||||
|
||||
@Binding var selectedUrl: URL?
|
||||
let supportedTypes: [String]
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(self)
|
||||
}
|
||||
|
||||
func makeUIViewController(context: Context) -> some UIViewController {
|
||||
|
||||
let documentPickerViewController = UIDocumentPickerViewController(documentTypes: supportedTypes, in: .import)
|
||||
documentPickerViewController.delegate = context.coordinator
|
||||
return documentPickerViewController
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}
|
||||
}
|
||||
|
||||
extension DocumentPicker.Coordinator: UIDocumentPickerDelegate {
|
||||
|
||||
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
|
||||
self.parent.selectedUrl = nil
|
||||
}
|
||||
|
||||
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
|
||||
|
||||
guard let firstURL = urls.first else {
|
||||
return
|
||||
}
|
||||
|
||||
self.parent.selectedUrl = firstURL
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// FilePreviewView.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Fabian Thies on 03.02.23.
|
||||
// Copyright © 2023 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
import QuickLook
|
||||
|
||||
struct FilePreviewView: UIViewControllerRepresentable {
|
||||
let urls: [URL]
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(urls: self.urls)
|
||||
}
|
||||
|
||||
func makeUIViewController(context: Context) -> some UIViewController {
|
||||
let previewController = QLPreviewController()
|
||||
previewController.dataSource = context.coordinator
|
||||
return UINavigationController(rootViewController: previewController)
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
|
||||
context.coordinator.urls = self.urls
|
||||
}
|
||||
}
|
||||
|
||||
extension FilePreviewView {
|
||||
|
||||
class Coordinator: QLPreviewControllerDataSource {
|
||||
var urls: [URL]
|
||||
|
||||
init(urls: [URL]) {
|
||||
self.urls = urls
|
||||
}
|
||||
|
||||
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
|
||||
urls.count
|
||||
}
|
||||
|
||||
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
|
||||
urls[index] as QLPreviewItem
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// MailComposeView.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Fabian Thies on 04.02.23.
|
||||
// Copyright © 2023 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MessageUI
|
||||
|
||||
struct MailComposeView: UIViewControllerRepresentable {
|
||||
typealias ActionHandler = () -> Void
|
||||
typealias ErrorHandler = (Error) -> Void
|
||||
|
||||
static var canSendMail: Bool {
|
||||
MFMailComposeViewController.canSendMail()
|
||||
}
|
||||
|
||||
let recipients: [String]
|
||||
let subject: String
|
||||
var body: String? = nil
|
||||
|
||||
var onMailSent: ActionHandler? = nil
|
||||
var onError: ErrorHandler? = nil
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(mailSentHandler: self.onMailSent, errorHandler: self.onError)
|
||||
}
|
||||
|
||||
func makeUIViewController(context: Context) -> some UIViewController {
|
||||
let mailViewController = MFMailComposeViewController()
|
||||
mailViewController.mailComposeDelegate = context.coordinator
|
||||
mailViewController.setToRecipients(self.recipients)
|
||||
mailViewController.setSubject(self.subject)
|
||||
|
||||
if let body {
|
||||
mailViewController.setMessageBody(body, isHTML: false)
|
||||
}
|
||||
|
||||
return mailViewController
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension MailComposeView {
|
||||
class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
|
||||
|
||||
let mailSentHandler: ActionHandler?
|
||||
let errorHandler: ErrorHandler?
|
||||
|
||||
init(mailSentHandler: ActionHandler?, errorHandler: ErrorHandler?) {
|
||||
self.mailSentHandler = mailSentHandler
|
||||
self.errorHandler = errorHandler
|
||||
super.init()
|
||||
}
|
||||
|
||||
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
|
||||
if result == .sent, let mailSentHandler {
|
||||
mailSentHandler()
|
||||
} else if result == .failed, let errorHandler, let error {
|
||||
errorHandler(error)
|
||||
}
|
||||
|
||||
controller.dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// SafariView.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Fabian Thies on 18.11.22.
|
||||
// Copyright © 2022 Fabian Thies. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import SafariServices
|
||||
|
||||
struct SafariView: UIViewControllerRepresentable {
|
||||
let url: URL
|
||||
|
||||
func makeUIViewController(context: Context) -> some UIViewController {
|
||||
SFSafariViewController(url: url)
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// SiriShortcutSetupView.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Fabian Thies on 21.11.22.
|
||||
// Copyright © 2022 Fabian Thies. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
import UIKit
|
||||
import Intents
|
||||
import IntentsUI
|
||||
|
||||
struct SiriShortcutSetupView: UIViewControllerRepresentable {
|
||||
|
||||
let shortcut: INShortcut
|
||||
|
||||
func makeUIViewController(context: Context) -> some UIViewController {
|
||||
let viewController = INUIAddVoiceShortcutViewController(shortcut: shortcut)
|
||||
viewController.delegate = context.coordinator
|
||||
viewController.modalPresentationStyle = .formSheet
|
||||
return viewController
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(shortcut: shortcut)
|
||||
}
|
||||
|
||||
class Coordinator: NSObject {
|
||||
|
||||
let shortcut: INShortcut
|
||||
|
||||
init(shortcut: INShortcut) {
|
||||
self.shortcut = shortcut
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SiriShortcutSetupView.Coordinator: INUIAddVoiceShortcutViewControllerDelegate {
|
||||
func addVoiceShortcutViewController(_ controller: INUIAddVoiceShortcutViewController, didFinishWith voiceShortcut: INVoiceShortcut?, error: Error?) {
|
||||
|
||||
// TODO: Handle errors
|
||||
controller.dismiss(animated: true)
|
||||
}
|
||||
|
||||
func addVoiceShortcutViewControllerDidCancel(_ controller: INUIAddVoiceShortcutViewController) {
|
||||
controller.dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// VisualEffectView.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Fabian Thies on 01.12.22.
|
||||
// Copyright © 2022 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct VisualEffectView: UIViewRepresentable {
|
||||
let blurStyle: UIBlurEffect.Style
|
||||
|
||||
func makeUIView(context: Context) -> some UIView {
|
||||
UIVisualEffectView(effect: UIBlurEffect(style: blurStyle))
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: UIViewType, context: Context) { }
|
||||
}
|
||||
|
||||
|
||||
extension View {
|
||||
@ViewBuilder
|
||||
func blurBackground(_ style: UIBlurEffect.Style) -> some View {
|
||||
self
|
||||
.background(VisualEffectView(blurStyle: style))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user