mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-03 16:41:26 +01:00
feat(core,app,android,ios): add a first share without a detour or a name to invent
The empty library said to add a link "under Shares, then refresh" with nothing to press on the phones, and on the desktop only switched page. All three now open the add form from there, the desktop with the caret in the link field; and adding already crawls, so there is nothing to refresh. A share's name was required before the viewer had seen anything to name. It is optional now: without one, ShareStore::add_verified takes the shared folder's own name from the link it has just opened. The link comes first in each form. The desktop form submits on Enter, and the Android link field has an eye to check what was pasted.
This commit is contained in:
1 parent
5807493a4a
commit
603cc0c1a9
14 files changed
+153
-50
No files matched your search
@@ -194,7 +194,15 @@ struct RootView: View {
|
||||
/// tap rather than back and in again.
|
||||
@ViewBuilder private func libraryPage(width: CGFloat) -> some View {
|
||||
let selected = selectedTitleKey.flatMap { key in model.titles.first { $0.key == key } }
|
||||
let library = LibraryView(onResume: play, onTitle: { title in withAnimation(.easeOut(duration: 0.25)) { selectedTitleKey = title.key } })
|
||||
let library = LibraryView(
|
||||
onResume: play,
|
||||
onTitle: { title in withAnimation(.easeOut(duration: 0.25)) { selectedTitleKey = title.key } },
|
||||
// The form as a pasted link opens it, only with nothing in it.
|
||||
onAddShare: {
|
||||
incomingLink = ""
|
||||
destination = .shares
|
||||
}
|
||||
)
|
||||
if width >= twoPaneWidth {
|
||||
HStack(spacing: 0) {
|
||||
library.frame(width: width * 0.45)
|
||||
|
||||
@@ -79,17 +79,22 @@ struct IconButton: View {
|
||||
struct EmptyState: View {
|
||||
let title: String
|
||||
let body_: String
|
||||
let action: (label: String, run: () -> Void)?
|
||||
@Environment(\.scheme) private var scheme
|
||||
|
||||
init(_ title: String, _ body: String) {
|
||||
init(_ title: String, _ body: String, action: (label: String, run: () -> Void)? = nil) {
|
||||
self.title = title
|
||||
body_ = body
|
||||
self.action = action
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 2) {
|
||||
Text(title).textStyle(.titleMedium).foregroundStyle(scheme.onSurface)
|
||||
Text(body_).textStyle(.bodyMedium).foregroundStyle(scheme.onSurface)
|
||||
Text(body_).textStyle(.bodyMedium).foregroundStyle(scheme.onSurfaceVariant)
|
||||
if let action {
|
||||
Button(action.label, action: action.run).buttonStyle(.accent).padding(.top, 16)
|
||||
}
|
||||
}
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(24)
|
||||
|
||||
@@ -57,6 +57,7 @@ struct LibraryView: View {
|
||||
@Environment(\.scheme) private var scheme
|
||||
let onResume: (TitleRecord, Int) -> Void
|
||||
let onTitle: (TitleRecord) -> Void
|
||||
var onAddShare: () -> Void = {}
|
||||
|
||||
// What a long press opened a menu for: a title, or a Continue watching card.
|
||||
@State private var menuFor: TitleRecord?
|
||||
@@ -146,7 +147,11 @@ struct LibraryView: View {
|
||||
EmptyState("Nothing matches", "No title in the library is called “\(model.query.trimmingCharacters(in: .whitespaces))”.")
|
||||
} else if model.titles.isEmpty {
|
||||
ScrollView {
|
||||
EmptyState("Your library is empty", "Add a Proton Drive public link under Shares, then refresh.")
|
||||
EmptyState(
|
||||
"Your library is empty",
|
||||
"Add a Proton Drive share link, and everything playable behind it shows up here.",
|
||||
action: ("Add a share", onAddShare)
|
||||
)
|
||||
.containerRelativeFrame(.vertical)
|
||||
}
|
||||
.refreshable { await model.crawlNow(nil) }
|
||||
|
||||
@@ -211,15 +211,14 @@ private struct AddShareSheet: View {
|
||||
}
|
||||
|
||||
private var ready: Bool {
|
||||
!name.trimmingCharacters(in: .whitespaces).isEmpty && !url.trimmingCharacters(in: .whitespaces).isEmpty
|
||||
!url.trimmingCharacters(in: .whitespaces).isEmpty
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
DialogSheet("Add Proton Drive share") {
|
||||
Field(label: "Library name", text: $name)
|
||||
// The URL fragment is a secret, so the field is a secure one: no
|
||||
// keyboard learning, no suggestions, and paste still works.
|
||||
Field(label: "Public share URL", text: $url, secret: true)
|
||||
Field(label: "Share link", text: $url, secret: true)
|
||||
// There is no share sheet into a sideloaded app, so a link copied
|
||||
// elsewhere comes in from the clipboard.
|
||||
if url.isEmpty {
|
||||
@@ -230,6 +229,8 @@ private struct AddShareSheet: View {
|
||||
}
|
||||
.buttonStyle(.quiet)
|
||||
}
|
||||
// Without one, the shared folder's own name.
|
||||
Field(label: "Name (optional)", text: $name)
|
||||
Field(label: "Custom password (optional)", text: $password, secret: true)
|
||||
if adding {
|
||||
HStack(spacing: 12) {
|
||||
|
||||
Reference in new issue
Block a user