v1.0.2: Избранное (метка + вкладка), Доступные мне (реестр публичных ссылок)
- Избранное: правый клик → «В избранное», звезда в строке, метки в UserDefaults, вкладка подгружает ресурсы по путям - Доступные мне: кнопка «+» добавляет публичную ссылку; метаданные через официальный GET /v1/disk/public/resources; открытие/копирование/удаление - Ограничение платформы задокументировано (ПРАВКИ.md): REST API не отдаёт список shared-with-me - smoke_test: фикс пути бандла
This commit is contained in:
@@ -6,6 +6,8 @@ struct MainSplitView: View {
|
||||
@Environment(\.openWindow) private var openWindow
|
||||
@State private var showNewFolderAlert = false
|
||||
@State private var newFolderName = ""
|
||||
@State private var showAddLinkAlert = false
|
||||
@State private var newLinkText = ""
|
||||
@State private var renameItem: DiskResource?
|
||||
@State private var renameText = ""
|
||||
|
||||
@@ -56,6 +58,14 @@ struct MainSplitView: View {
|
||||
}
|
||||
.toolbar {
|
||||
ToolbarItemGroup {
|
||||
if store.sidebarSelection == .files {
|
||||
Button {
|
||||
showAddLinkAlert = true
|
||||
} label: {
|
||||
Label("Добавить публичную ссылку", systemImage: "plus")
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
showNewFolderAlert = true
|
||||
} label: {
|
||||
@@ -116,6 +126,17 @@ struct MainSplitView: View {
|
||||
}
|
||||
Button("Отмена", role: .cancel) {}
|
||||
}
|
||||
.alert("Публичная ссылка", isPresented: $showAddLinkAlert) {
|
||||
TextField("https://disk.yandex.ru/d/…", text: $newLinkText)
|
||||
Button("Добавить") {
|
||||
let link = newLinkText
|
||||
newLinkText = ""
|
||||
Task { await store.addPublicLink(link) }
|
||||
}
|
||||
Button("Отмена", role: .cancel) {}
|
||||
} message: {
|
||||
Text("Вставьте ссылку, которой поделился другой пользователь (папка «Общий доступ» на disk.yandex.ru → «Поделиться ссылкой»).")
|
||||
}
|
||||
.alert("Переименовать", isPresented: Binding(
|
||||
get: { renameItem != nil },
|
||||
set: { if !$0 { renameItem = nil } }
|
||||
@@ -182,11 +203,30 @@ struct MainSplitView: View {
|
||||
switch store.sidebarSelection {
|
||||
case .trash: return store.trashItems
|
||||
case .recents: return store.recentItems
|
||||
case .files: return [] // «Доступные мне» — заглушка до реализации API
|
||||
case .favorites: return store.favoriteItems
|
||||
case .files: return store.publicItems
|
||||
default: return store.filteredItems
|
||||
}
|
||||
}
|
||||
|
||||
private var emptyIcon: String {
|
||||
switch store.sidebarSelection {
|
||||
case .trash: return "trash"
|
||||
case .favorites: return "star"
|
||||
case .files: return "person.2"
|
||||
default: return "folder"
|
||||
}
|
||||
}
|
||||
|
||||
private var emptyText: String {
|
||||
switch store.sidebarSelection {
|
||||
case .trash: return "Корзина пуста"
|
||||
case .favorites: return "Нет избранного — правый клик по файлу → «В избранное»"
|
||||
case .files: return "Нет общих ссылок — нажмите «+», чтобы добавить публичную ссылку"
|
||||
default: return "Папка пуста"
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func fileBrowser(store: AppStore) -> some View {
|
||||
let items = visibleItems(store: store)
|
||||
@@ -195,10 +235,10 @@ struct MainSplitView: View {
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
} else if items.isEmpty {
|
||||
VStack(spacing: 12) {
|
||||
Image(systemName: store.sidebarSelection == .trash ? "trash" : "folder")
|
||||
Image(systemName: emptyIcon)
|
||||
.font(.system(size: 40))
|
||||
.foregroundStyle(.tertiary)
|
||||
Text(store.sidebarSelection == .trash ? "Корзина пуста" : "Папка пуста")
|
||||
Text(emptyText)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
@@ -214,6 +254,11 @@ struct MainSplitView: View {
|
||||
.frame(width: 18)
|
||||
Text(item.displayName)
|
||||
.lineLimit(1)
|
||||
if store.sidebarSelection != .files && store.isFavorite(item) {
|
||||
Image(systemName: "star.fill")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.yellow)
|
||||
}
|
||||
if item.publicUrl != nil {
|
||||
Image(systemName: "link")
|
||||
.font(.caption2)
|
||||
@@ -262,7 +307,20 @@ struct MainSplitView: View {
|
||||
Button("Восстановить") {
|
||||
Task { await store.restoreFromTrash(item) }
|
||||
}
|
||||
} else if store.sidebarSelection == .files {
|
||||
Button("Открыть в браузере") { store.open(item) }
|
||||
Button("Скопировать ссылку") {
|
||||
NSPasteboard.general.clearContents()
|
||||
NSPasteboard.general.setString(item.path, forType: .string)
|
||||
}
|
||||
Divider()
|
||||
Button("Убрать из «Доступные мне»", role: .destructive) {
|
||||
store.removePublicLink(item)
|
||||
}
|
||||
} else {
|
||||
Button(store.isFavorite(item) ? "Убрать из избранного" : "В избранное") {
|
||||
store.toggleFavorite(item)
|
||||
}
|
||||
Button("Открыть") { store.open(item) }
|
||||
Button("Показать в Finder") { store.revealInFinder(item) }
|
||||
Button("Создать копию на компьютере") {
|
||||
|
||||
Reference in New Issue
Block a user