mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 13:33:42 +00:00
Add recent documents to home on iOS
This commit is contained in:
parent
8ec06b0d59
commit
bc1571a746
@ -54,6 +54,19 @@ final class DocumentsModel: ObservableObject {
|
||||
return nil
|
||||
}
|
||||
|
||||
func recentDocuments(_ limit: Int = 10) -> [URL] {
|
||||
guard let documentsDirectory else { return [] }
|
||||
|
||||
return Array(
|
||||
contents(of: documentsDirectory)
|
||||
.sorted {
|
||||
((try? $0.resourceValues(forKeys: [.creationDateKey]).creationDate) ?? Date()) >
|
||||
((try? $1.resourceValues(forKeys: [.creationDateKey]).creationDate) ?? Date())
|
||||
}
|
||||
.prefix(limit)
|
||||
)
|
||||
}
|
||||
|
||||
func isDocument(_ video: Video) -> Bool {
|
||||
guard video.isLocal, let url = video.localStream?.localURL, let url = replacePrivateVar(url) else { return false }
|
||||
return isDocument(url)
|
||||
|
@ -22,10 +22,13 @@ extension Defaults.Keys {
|
||||
static let enableReturnYouTubeDislike = Key<Bool>("enableReturnYouTubeDislike", default: false)
|
||||
|
||||
static let showHome = Key<Bool>("showHome", default: true)
|
||||
static let showDocuments = Key<Bool>("showDocuments", default: true)
|
||||
static let showOpenActionsInHome = Key<Bool>("showOpenActionsInHome", default: true)
|
||||
static let showOpenActionsToolbarItem = Key<Bool>("showOpenActionsToolbarItem", default: false)
|
||||
static let showFavoritesInHome = Key<Bool>("showFavoritesInHome", default: true)
|
||||
#if os(iOS)
|
||||
static let showDocuments = Key<Bool>("showDocuments", default: false)
|
||||
static let homeRecentDocumentsItems = Key<Int>("homeRecentDocumentsItems", default: 3)
|
||||
#endif
|
||||
static let homeHistoryItems = Key<Int>("homeHistoryItems", default: 10)
|
||||
static let favorites = Key<[FavoriteItem]>("favorites", default: [])
|
||||
|
||||
|
@ -7,16 +7,7 @@ struct DocumentsView: View {
|
||||
BrowserPlayerControls {
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
if model.directoryContents.isEmpty {
|
||||
VStack(alignment: .center, spacing: 20) {
|
||||
HStack {
|
||||
Image(systemName: "doc")
|
||||
Text("No documents")
|
||||
}
|
||||
Text("Share files from Finder on a Mac\nor iTunes on Windows")
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.foregroundColor(.secondary)
|
||||
NoDocumentsView()
|
||||
} else {
|
||||
ForEach(model.sortedDirectoryContents, id: \.absoluteString) { url in
|
||||
let video = Video.local(model.replacePrivateVar(url) ?? url)
|
||||
|
22
Shared/Documents/NoDocumentsView.swift
Normal file
22
Shared/Documents/NoDocumentsView.swift
Normal file
@ -0,0 +1,22 @@
|
||||
import SwiftUI
|
||||
|
||||
struct NoDocumentsView: View {
|
||||
var body: some View {
|
||||
VStack(alignment: .center, spacing: 20) {
|
||||
HStack {
|
||||
Image(systemName: "doc")
|
||||
Text("No documents")
|
||||
}
|
||||
Text("Share files from Finder on a Mac\nor iTunes on Windows")
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
struct NoDocumentsView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
NoDocumentsView()
|
||||
}
|
||||
}
|
36
Shared/Documents/RecentDocumentsView.swift
Normal file
36
Shared/Documents/RecentDocumentsView.swift
Normal file
@ -0,0 +1,36 @@
|
||||
import Defaults
|
||||
import SwiftUI
|
||||
|
||||
struct RecentDocumentsView: View {
|
||||
var limit = 3
|
||||
let model = DocumentsModel.shared
|
||||
|
||||
var body: some View {
|
||||
LazyVStack {
|
||||
if recentDocuments.isEmpty {
|
||||
NoDocumentsView()
|
||||
} else {
|
||||
ForEach(recentDocuments, id: \.absoluteString) { url in
|
||||
let video = Video.local(model.replacePrivateVar(url) ?? url)
|
||||
PlayerQueueRow(
|
||||
item: PlayerQueueItem(video)
|
||||
)
|
||||
.contextMenu {
|
||||
VideoContextMenuView(video: video)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 15)
|
||||
}
|
||||
|
||||
var recentDocuments: [URL] {
|
||||
model.recentDocuments(limit)
|
||||
}
|
||||
}
|
||||
|
||||
struct RecentDocumentsView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
RecentDocumentsView()
|
||||
}
|
||||
}
|
@ -15,12 +15,18 @@ struct HomeView: View {
|
||||
@FetchRequest(sortDescriptors: [.init(key: "watchedAt", ascending: false)])
|
||||
var watches: FetchedResults<Watch>
|
||||
@State private var historyID = UUID()
|
||||
#if os(iOS)
|
||||
@State private var recentDocumentsID = UUID()
|
||||
#endif
|
||||
|
||||
var favoritesObserver: Any?
|
||||
|
||||
#if !os(tvOS)
|
||||
@Default(.favorites) private var favorites
|
||||
#endif
|
||||
#if os(iOS)
|
||||
@Default(.homeRecentDocumentsItems) private var homeRecentDocumentsItems
|
||||
#endif
|
||||
@Default(.homeHistoryItems) private var homeHistoryItems
|
||||
@Default(.showFavoritesInHome) private var showFavoritesInHome
|
||||
@Default(.showOpenActionsInHome) private var showOpenActionsInHome
|
||||
@ -87,10 +93,33 @@ struct HomeView: View {
|
||||
#endif
|
||||
}
|
||||
|
||||
if homeRecentDocumentsItems > 0 {
|
||||
VStack {
|
||||
HStack {
|
||||
sectionLabel("Recent Documents")
|
||||
|
||||
Spacer()
|
||||
|
||||
Button {
|
||||
recentDocumentsID = UUID()
|
||||
} label: {
|
||||
Label("Refresh", systemImage: "arrow.clockwise")
|
||||
.font(.headline)
|
||||
.labelStyle(.iconOnly)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
RecentDocumentsView(limit: homeRecentDocumentsItems)
|
||||
.id(recentDocumentsID)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
|
||||
if homeHistoryItems > 0 {
|
||||
VStack {
|
||||
HStack {
|
||||
Text("History")
|
||||
sectionLabel("History")
|
||||
Spacer()
|
||||
Button {
|
||||
navigation.presentAlert(
|
||||
@ -108,17 +137,11 @@ struct HomeView: View {
|
||||
Label("Clear History", systemImage: "trash")
|
||||
.font(.headline)
|
||||
.labelStyle(.iconOnly)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
#if os(tvOS)
|
||||
.padding(.horizontal, 40)
|
||||
#else
|
||||
.padding(.horizontal, 15)
|
||||
#endif
|
||||
.font(.title3.bold())
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.foregroundColor(.secondary)
|
||||
|
||||
HistoryView(limit: homeHistoryItems)
|
||||
.id(historyID)
|
||||
@ -157,9 +180,21 @@ struct HomeView: View {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
func sectionLabel(_ label: String) -> some View {
|
||||
Text(label)
|
||||
#if os(tvOS)
|
||||
.padding(.horizontal, 40)
|
||||
#else
|
||||
.padding(.horizontal, 15)
|
||||
#endif
|
||||
.font(.title3.bold())
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
struct Favorites_Previews: PreviewProvider {
|
||||
struct Home_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
TabView {
|
||||
HomeView()
|
||||
|
@ -8,6 +8,7 @@ struct BrowsingSettings: View {
|
||||
#endif
|
||||
@Default(.accountPickerDisplaysAnonymousAccounts) private var accountPickerDisplaysAnonymousAccounts
|
||||
#if os(iOS)
|
||||
@Default(.homeRecentDocumentsItems) private var homeRecentDocumentsItems
|
||||
@Default(.lockPortraitWhenBrowsing) private var lockPortraitWhenBrowsing
|
||||
#endif
|
||||
@Default(.thumbnailsQuality) private var thumbnailsQuality
|
||||
@ -24,6 +25,9 @@ struct BrowsingSettings: View {
|
||||
@EnvironmentObject<AccountsModel> private var accounts
|
||||
|
||||
@State private var homeHistoryItemsText = ""
|
||||
#if os(iOS)
|
||||
@State private var homeRecentDocumentsItemsText = ""
|
||||
#endif
|
||||
#if os(macOS)
|
||||
@State private var presentingEditFavoritesSheet = false
|
||||
#endif
|
||||
@ -87,6 +91,22 @@ struct BrowsingSettings: View {
|
||||
}
|
||||
.multilineTextAlignment(.trailing)
|
||||
|
||||
HStack {
|
||||
Text("Recent documents")
|
||||
TextField("Recent documents", text: $homeRecentDocumentsItemsText)
|
||||
.labelsHidden()
|
||||
#if !os(macOS)
|
||||
.keyboardType(.numberPad)
|
||||
#endif
|
||||
.onAppear {
|
||||
homeRecentDocumentsItemsText = String(homeRecentDocumentsItems)
|
||||
}
|
||||
.onChange(of: homeRecentDocumentsItemsText) { newValue in
|
||||
homeRecentDocumentsItems = Int(newValue) ?? 3
|
||||
}
|
||||
}
|
||||
.multilineTextAlignment(.trailing)
|
||||
|
||||
if !accounts.isEmpty {
|
||||
Toggle("Show Favorites", isOn: $showFavoritesInHome)
|
||||
|
||||
|
@ -77,6 +77,8 @@
|
||||
3705B182267B4E4900704544 /* TrendingCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3705B181267B4E4900704544 /* TrendingCategory.swift */; };
|
||||
3705B183267B4E4900704544 /* TrendingCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3705B181267B4E4900704544 /* TrendingCategory.swift */; };
|
||||
3705B184267B4E4900704544 /* TrendingCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3705B181267B4E4900704544 /* TrendingCategory.swift */; };
|
||||
3709528829283A21001ECA40 /* RecentDocumentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3709528729283A21001ECA40 /* RecentDocumentsView.swift */; };
|
||||
3709528A29283E14001ECA40 /* NoDocumentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3709528929283E14001ECA40 /* NoDocumentsView.swift */; };
|
||||
37095E82291DC85400301883 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37095E81291DC85400301883 /* ShareViewController.swift */; };
|
||||
37095E89291DC85400301883 /* Open in Yattee.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 37095E7F291DC85400301883 /* Open in Yattee.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
37095E8D291DD5DA00301883 /* URLBookmarkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37F5E8B5291BE9D0006C15F5 /* URLBookmarkModel.swift */; };
|
||||
@ -1020,6 +1022,8 @@
|
||||
3703100127B0713600ECDDAA /* PlayerGestures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerGestures.swift; sourceTree = "<group>"; };
|
||||
3705B17F267B4DFB00704544 /* TrendingCountry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingCountry.swift; sourceTree = "<group>"; };
|
||||
3705B181267B4E4900704544 /* TrendingCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingCategory.swift; sourceTree = "<group>"; };
|
||||
3709528729283A21001ECA40 /* RecentDocumentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentDocumentsView.swift; sourceTree = "<group>"; };
|
||||
3709528929283E14001ECA40 /* NoDocumentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoDocumentsView.swift; sourceTree = "<group>"; };
|
||||
37095E7F291DC85400301883 /* Open in Yattee.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Open in Yattee.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
37095E81291DC85400301883 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||
37095E86291DC85400301883 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@ -1873,6 +1877,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
37494EA429200B14000DF176 /* DocumentsView.swift */,
|
||||
3709528929283E14001ECA40 /* NoDocumentsView.swift */,
|
||||
3709528729283A21001ECA40 /* RecentDocumentsView.swift */,
|
||||
);
|
||||
path = Documents;
|
||||
sourceTree = "<group>";
|
||||
@ -2873,6 +2879,7 @@
|
||||
375EC959289EEB8200751258 /* QualityProfileForm.swift in Sources */,
|
||||
37D2E0D028B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */,
|
||||
3727B74A27872A920021C15E /* VisualEffectBlur-iOS.swift in Sources */,
|
||||
3709528829283A21001ECA40 /* RecentDocumentsView.swift in Sources */,
|
||||
37977583268922F600DD52A8 /* InvidiousAPI.swift in Sources */,
|
||||
374AB3D728BCAF0000DF56FB /* SeekModel.swift in Sources */,
|
||||
37130A5F277657300033018A /* PersistenceController.swift in Sources */,
|
||||
@ -2916,6 +2923,7 @@
|
||||
37CC3F4C270CFE1700608308 /* PlayerQueueView.swift in Sources */,
|
||||
37FFC440272734C3009FFD26 /* Throttle.swift in Sources */,
|
||||
37DD9DB42785D58D00539416 /* RefreshControlModifier.swift in Sources */,
|
||||
3709528A29283E14001ECA40 /* NoDocumentsView.swift in Sources */,
|
||||
3705B182267B4E4900704544 /* TrendingCategory.swift in Sources */,
|
||||
378AE940274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */,
|
||||
376BE50927347B5F009AD608 /* SettingsHeader.swift in Sources */,
|
||||
|
Loading…
Reference in New Issue
Block a user