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.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. */
|
||||
@Composable
|
||||
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.Member
|
||||
import com.fabledsword.inkwell.core.NoteShare
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/** Everything the Share sheet renders from. [noteId] null means the sheet is closed. */
|
||||
data class ShareState(
|
||||
@@ -54,19 +56,19 @@ class ShareViewModel(
|
||||
fun open(noteId: String) {
|
||||
state = ShareState(noteId = noteId, loading = true)
|
||||
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 =
|
||||
try {
|
||||
val members = core.shareDirectory()
|
||||
val shares = core.noteShares(noteId)
|
||||
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) {
|
||||
if (!withContext(Dispatchers.IO) { core.syncStatus().linked }) {
|
||||
state.copy(loading = false, needsServer = true)
|
||||
} else {
|
||||
state.copy(loading = false, loadError = e.describeShareFailure())
|
||||
val members = core.shareDirectory()
|
||||
val shares = core.noteShares(noteId)
|
||||
state.copy(loading = false, members = members, shares = shares)
|
||||
}
|
||||
} catch (e: CoreException) {
|
||||
state.copy(loading = false, loadError = e.describeShareFailure())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user