android: detekt — check the link before loading shares, and NoteAccess gets its own file
Android / Build, or is the channel already serving this? (push) Successful in 4s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Build now, or wait for Android? (push) Successful in 3s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 3s
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Skipped
Desktop (Tauri) / Tauri desktop (Linux) (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Skipped
Desktop (Tauri) / Update manifest (push) Skipped
CI & Build / Web typecheck and unit tests (push) Successful in 10s
CI & Build / Python tests (push) Successful in 13s
CI & Build / integration (push) Successful in 1m6s
CI & Build / Build & push image (push) Skipped
Android / Kotlin + Rust (APK) (push) Successful in 7m27s
Android / Build, or is the channel already serving this? (push) Successful in 4s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Build now, or wait for Android? (push) Successful in 3s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 3s
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Skipped
Desktop (Tauri) / Tauri desktop (Linux) (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Skipped
Desktop (Tauri) / Update manifest (push) Skipped
CI & Build / Web typecheck and unit tests (push) Successful in 10s
CI & Build / Python tests (push) Successful in 13s
CI & Build / integration (push) Successful in 1m6s
CI & Build / Build & push image (push) Skipped
Android / Kotlin + Rust (APK) (push) Successful in 7m27s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
package com.fabledsword.inkwell.ui
|
||||||
|
|
||||||
|
import com.fabledsword.inkwell.core.Note
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How this account holds a note (#5175), read from the core's `permission`.
|
||||||
|
*
|
||||||
|
* Someone else's note at [EDIT] is theirs to have its TEXT changed here and nothing
|
||||||
|
* else; at [VIEW] nothing changes here at all. The core refuses the rest anyway —
|
||||||
|
* this only keeps the editor from offering what would be refused.
|
||||||
|
*/
|
||||||
|
enum class NoteAccess { OWNER, EDIT, VIEW }
|
||||||
|
|
||||||
|
val Note.access: NoteAccess
|
||||||
|
get() =
|
||||||
|
when (permission) {
|
||||||
|
"edit" -> NoteAccess.EDIT
|
||||||
|
"view" -> NoteAccess.VIEW
|
||||||
|
else -> NoteAccess.OWNER
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Nothing changes here: the note is in the trash, or shared with us to view. */
|
||||||
|
val Note.readOnlyHere: Boolean
|
||||||
|
get() = trashed || access == NoteAccess.VIEW
|
||||||
|
|
||||||
|
/** The owner's own controls apply: tags, reminder, files, previews, the menu. */
|
||||||
|
val Note.ownerControlsHere: Boolean
|
||||||
|
get() = !readOnlyHere && access == NoteAccess.OWNER
|
||||||
-25
@@ -36,31 +36,6 @@ import com.fabledsword.inkwell.core.Member
|
|||||||
import com.fabledsword.inkwell.core.Note
|
import com.fabledsword.inkwell.core.Note
|
||||||
import com.fabledsword.inkwell.core.NoteShare
|
import com.fabledsword.inkwell.core.NoteShare
|
||||||
|
|
||||||
/**
|
|
||||||
* How this account holds a note (#5175), read from the core's `permission`.
|
|
||||||
*
|
|
||||||
* Someone else's note at [EDIT] is theirs to have its TEXT changed here and nothing
|
|
||||||
* else; at [VIEW] nothing changes here at all. The core refuses the rest anyway —
|
|
||||||
* this only keeps the editor from offering what would be refused.
|
|
||||||
*/
|
|
||||||
enum class NoteAccess { OWNER, EDIT, VIEW }
|
|
||||||
|
|
||||||
val Note.access: NoteAccess
|
|
||||||
get() =
|
|
||||||
when (permission) {
|
|
||||||
"edit" -> NoteAccess.EDIT
|
|
||||||
"view" -> NoteAccess.VIEW
|
|
||||||
else -> NoteAccess.OWNER
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Nothing changes here: the note is in the trash, or shared with us to view. */
|
|
||||||
val Note.readOnlyHere: Boolean
|
|
||||||
get() = trashed || access == NoteAccess.VIEW
|
|
||||||
|
|
||||||
/** The owner's own controls apply: tags, reminder, files, previews, the menu. */
|
|
||||||
val Note.ownerControlsHere: Boolean
|
|
||||||
get() = !readOnlyHere && access == NoteAccess.OWNER
|
|
||||||
|
|
||||||
/** "Shared by Robin · view only" over someone else's note; nothing over our own. */
|
/** "Shared by Robin · view only" over someone else's note; nothing over our own. */
|
||||||
@Composable
|
@Composable
|
||||||
fun SharedByLine(note: Note) {
|
fun SharedByLine(note: Note) {
|
||||||
@@ -10,7 +10,9 @@ import com.fabledsword.inkwell.core.CoreException
|
|||||||
import com.fabledsword.inkwell.core.Inkwell
|
import com.fabledsword.inkwell.core.Inkwell
|
||||||
import com.fabledsword.inkwell.core.Member
|
import com.fabledsword.inkwell.core.Member
|
||||||
import com.fabledsword.inkwell.core.NoteShare
|
import com.fabledsword.inkwell.core.NoteShare
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
/** Everything the Share sheet renders from. [noteId] null means the sheet is closed. */
|
/** Everything the Share sheet renders from. [noteId] null means the sheet is closed. */
|
||||||
data class ShareState(
|
data class ShareState(
|
||||||
@@ -54,19 +56,19 @@ class ShareViewModel(
|
|||||||
fun open(noteId: String) {
|
fun open(noteId: String) {
|
||||||
state = ShareState(noteId = noteId, loading = true)
|
state = ShareState(noteId = noteId, loading = true)
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
// Unlinked is not a failure: it is the phone working as intended, so the
|
||||||
|
// sheet says what sharing needs rather than showing an error.
|
||||||
state =
|
state =
|
||||||
try {
|
try {
|
||||||
|
if (!withContext(Dispatchers.IO) { core.syncStatus().linked }) {
|
||||||
|
state.copy(loading = false, needsServer = true)
|
||||||
|
} else {
|
||||||
val members = core.shareDirectory()
|
val members = core.shareDirectory()
|
||||||
val shares = core.noteShares(noteId)
|
val shares = core.noteShares(noteId)
|
||||||
state.copy(loading = false, members = members, shares = shares)
|
state.copy(loading = false, members = members, shares = shares)
|
||||||
} catch (e: CoreException) {
|
|
||||||
// Unlinked is not a failure: it is the phone working as intended,
|
|
||||||
// and the sheet says what sharing needs instead of an error.
|
|
||||||
if (e is CoreException.NotLinked) {
|
|
||||||
state.copy(loading = false, needsServer = true)
|
|
||||||
} else {
|
|
||||||
state.copy(loading = false, loadError = e.describeShareFailure())
|
|
||||||
}
|
}
|
||||||
|
} catch (e: CoreException) {
|
||||||
|
state.copy(loading = false, loadError = e.describeShareFailure())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user