mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-17 02:33:27 +01:00
[ADD] News, Browse and Settings views ported to SwiftUI
This commit contains WIP SwiftUI versions of most of the views in SideStore.
This commit is contained in:
101
AltStore/Views/News/NewsItemView.swift
Normal file
101
AltStore/Views/News/NewsItemView.swift
Normal file
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// NewsItemView.swift
|
||||
// SideStoreUI
|
||||
//
|
||||
// Created by Fabian Thies on 18.11.22.
|
||||
// Copyright © 2022 Fabian Thies. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AltStoreCore
|
||||
|
||||
struct NewsItemView: View {
|
||||
typealias TapHandler<T> = (T) -> Void
|
||||
|
||||
let newsItem: NewsItem
|
||||
|
||||
private var newsSelectionHandler: TapHandler<NewsItem>? = nil
|
||||
private var appSelectionHandler: TapHandler<StoreApp>? = nil
|
||||
|
||||
init(newsItem: NewsItem) {
|
||||
self.newsItem = newsItem
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 12) {
|
||||
newsContent
|
||||
.onTapGesture {
|
||||
newsSelectionHandler?(newsItem)
|
||||
}
|
||||
|
||||
if let connectedApp = newsItem.storeApp {
|
||||
NavigationLink {
|
||||
AppDetailView(storeApp: connectedApp)
|
||||
} label: {
|
||||
AppRowView(app: connectedApp)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var newsContent: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
Text(newsItem.title)
|
||||
.font(.title2)
|
||||
.bold()
|
||||
.foregroundColor(.white)
|
||||
|
||||
Text(newsItem.caption)
|
||||
.foregroundColor(.white.opacity(0.7))
|
||||
}
|
||||
.padding(24)
|
||||
|
||||
if let imageUrl = newsItem.imageURL, #available(iOS 15.0, *) {
|
||||
AsyncImage(
|
||||
url: imageUrl,
|
||||
content: { image in
|
||||
if let image = image.image {
|
||||
image
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
.frame(
|
||||
maxWidth: .infinity,
|
||||
alignment: .topLeading
|
||||
)
|
||||
.background(Color(newsItem.tintColor))
|
||||
.clipShape(RoundedRectangle(cornerRadius: 30, style: .circular))
|
||||
}
|
||||
|
||||
|
||||
func onNewsSelection(_ handler: @escaping TapHandler<NewsItem>) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.newsSelectionHandler = handler
|
||||
return newSelf
|
||||
}
|
||||
|
||||
func onAppSelection(_ handler: @escaping TapHandler<StoreApp>) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.appSelectionHandler = handler
|
||||
return newSelf
|
||||
}
|
||||
}
|
||||
|
||||
extension URL: Identifiable {
|
||||
public var id: String {
|
||||
return self.absoluteString
|
||||
}
|
||||
}
|
||||
|
||||
//struct NewsItemView_Previews: PreviewProvider {
|
||||
// static var previews: some View {
|
||||
// NewsItemView()
|
||||
// }
|
||||
//}
|
||||
55
AltStore/Views/News/NewsView.swift
Normal file
55
AltStore/Views/News/NewsView.swift
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// NewsView.swift
|
||||
// SideStoreUI
|
||||
//
|
||||
// Created by Fabian Thies on 18.11.22.
|
||||
// Copyright © 2022 Fabian Thies. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AltStoreCore
|
||||
|
||||
struct NewsView: View {
|
||||
|
||||
@SwiftUI.FetchRequest(sortDescriptors: [
|
||||
NSSortDescriptor(keyPath: \NewsItem.date, ascending: false),
|
||||
NSSortDescriptor(keyPath: \NewsItem.sortIndex, ascending: true),
|
||||
NSSortDescriptor(keyPath: \NewsItem.sourceIdentifier, ascending: true)
|
||||
])
|
||||
var news: FetchedResults<NewsItem>
|
||||
|
||||
@State
|
||||
var activeExternalUrl: URL?
|
||||
|
||||
@State
|
||||
var selectedStoreApp: StoreApp?
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
LazyVStack(spacing: 24) {
|
||||
ForEach(news, id: \.objectID) { newsItem in
|
||||
NewsItemView(newsItem: newsItem)
|
||||
.onNewsSelection { newsItem in
|
||||
self.activeExternalUrl = newsItem.externalURL
|
||||
}
|
||||
.frame(
|
||||
maxWidth: .infinity,
|
||||
alignment: .topLeading
|
||||
)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.background(Color(UIColor.systemGroupedBackground).ignoresSafeArea())
|
||||
.navigationTitle("News")
|
||||
.sheet(item: self.$activeExternalUrl) { url in
|
||||
SafariView(url: url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct NewsView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
NewsView()
|
||||
}
|
||||
}
|
||||
22
AltStore/Views/News/NewsViewModel.swift
Normal file
22
AltStore/Views/News/NewsViewModel.swift
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// NewsViewModel.swift
|
||||
// SideStoreUI
|
||||
//
|
||||
// Created by Fabian Thies on 18.11.22.
|
||||
// Copyright © 2022 Fabian Thies. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AltStoreCore
|
||||
|
||||
class NewsViewModel: ViewModel {
|
||||
|
||||
@SwiftUI.FetchRequest(sortDescriptors: [
|
||||
NSSortDescriptor(keyPath: \NewsItem.date, ascending: false),
|
||||
NSSortDescriptor(keyPath: \NewsItem.sortIndex, ascending: true),
|
||||
NSSortDescriptor(keyPath: \NewsItem.sourceIdentifier, ascending: true)
|
||||
])
|
||||
var news: FetchedResults<NewsItem>
|
||||
|
||||
init() {}
|
||||
}
|
||||
Reference in New Issue
Block a user