core: shared notes on the desktop and phone, and Share from the desktop
CI & Build / Python lint (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
Android / Build, or is the channel already serving this? (push) Successful in 4s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 3s
CI & Build / Web typecheck and unit tests (push) Successful in 9s
CI & Build / Python tests (push) Successful in 12s
CI & Build / integration (push) Successful in 1m14s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Failing after 1m26s
Desktop (Tauri) / Tauri desktop (Linux) (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Skipped
Desktop (Tauri) / Update manifest (push) Skipped
Android / Kotlin + Rust (APK) (push) Canceled after 9m20s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
Android / Build, or is the channel already serving this? (push) Successful in 4s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 3s
CI & Build / Web typecheck and unit tests (push) Successful in 9s
CI & Build / Python tests (push) Successful in 12s
CI & Build / integration (push) Successful in 1m14s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Failing after 1m26s
Desktop (Tauri) / Tauri desktop (Linux) (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Skipped
Desktop (Tauri) / Update manifest (push) Skipped
Android / Kotlin + Rust (APK) (push) Canceled after 9m20s
The core pulls with shares from a server offering them (protocol 6): a note says how it is held (owner, edit, view) and who shared it, and a revoked note leaves the device. The first such pull starts the feed over once, so notes shared before this build arrive. The store refuses what a share doesn't allow (view: everything; edit: anything but the text), push sends only the text of someone else's note, and their notes stay out of trash, reminders and reordering. Unlinking drops them. The Share dialog's calls go to the linked server over the device token, as Tauri commands and through the FFI. The desktop now offers Share and "Shared with me"; unlinked, the dialog says sharing needs a server. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -92,12 +92,12 @@ export const local: Repo = {
|
||||
rename: (id, name) => invoke<SavedFilter>("saved_filters_rename", { id, name }),
|
||||
},
|
||||
|
||||
// Sharing is between accounts on a server; the desktop gets it with sync (#5175).
|
||||
// The Share controls are not shown here, so these only answer a stray call.
|
||||
// Sharing is between accounts on a server, so these go to the linked one (#5175).
|
||||
// Unlinked, each rejects with the core's explanation, which the dialog shows.
|
||||
shares: {
|
||||
directory: () => Promise.resolve<Member[]>([]),
|
||||
list: () => Promise.resolve<NoteShare[]>([]),
|
||||
share: () => Promise.reject<NoteShare[]>(new Error(NEEDS_SERVER)),
|
||||
unshare: () => Promise.reject<NoteShare[]>(new Error(NEEDS_SERVER)),
|
||||
directory: () => invoke<Member[]>("shares_directory"),
|
||||
list: (noteId) => invoke<NoteShare[]>("shares_list", { noteId }),
|
||||
share: (noteId, userId, permission) => invoke<NoteShare[]>("shares_share", { noteId, userId, permission }),
|
||||
unshare: (noteId, shareId) => invoke<NoteShare[]>("shares_unshare", { noteId, shareId }),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -9,7 +9,6 @@ import { facetCount, facetsFromQuery, facetsToQuery } from "../notes/facets";
|
||||
import { addLocalDays, formatLocalDay, parseLocalDate } from "../notes/datetime";
|
||||
import Icon from "./Icon.vue";
|
||||
import { errorMessage } from "../api/errors";
|
||||
import { isDesktop } from "../desktop/bridge";
|
||||
|
||||
// A dead-simple facet bar over the board: color + labels + has-reminder
|
||||
// + has-attachment + created-date range. The URL query IS the state, so a
|
||||
@@ -44,9 +43,6 @@ function toggleReminder() {
|
||||
function toggleAttachment() {
|
||||
patch({ has_attachment: facets.value.has_attachment ? undefined : true });
|
||||
}
|
||||
// Sharing is between accounts on a server, so the offline desktop has no shared notes
|
||||
// to narrow to (#5174).
|
||||
const sharingAvailable = !isDesktop();
|
||||
function toggleShared() {
|
||||
patch({ shared: facets.value.shared ? undefined : "with_me" });
|
||||
}
|
||||
@@ -137,7 +133,6 @@ const chipOff = "border-neutral-300 text-neutral-600 hover:bg-neutral-100 dark:b
|
||||
Has attachment
|
||||
</button>
|
||||
<button
|
||||
v-if="sharingAvailable"
|
||||
type="button"
|
||||
:class="[chipBase, facets.shared ? chipOn : chipOff]"
|
||||
@click="toggleShared"
|
||||
|
||||
@@ -18,7 +18,6 @@ import { formatReminder, formatTrashCountdown, isOverdue, trashDaysLeft } from "
|
||||
import { useConfigStore } from "../stores/config";
|
||||
import { useUiStore } from "../stores/ui";
|
||||
import { canEditText, isOwnNote } from "../notes/sharing";
|
||||
import { isDesktop } from "../desktop/bridge";
|
||||
|
||||
const props = defineProps<{ note: Note; reorderable?: boolean; active?: boolean }>();
|
||||
const emit = defineEmits<{
|
||||
@@ -38,11 +37,12 @@ const config = useConfigStore();
|
||||
const ui = useUiStore();
|
||||
|
||||
// --- Sharing (#5174). Someone else's note shows who shared it and offers none of
|
||||
// the owner's controls; at `view` its checkboxes are inert too. Sharing needs a
|
||||
// server, so the offline desktop has no Share button (its notes are all its own). ---
|
||||
// the owner's controls; at `view` its checkboxes are inert too. The desktop offers
|
||||
// Share as well: linked it goes through the server, unlinked the dialog says sharing
|
||||
// needs one (#5175). ---
|
||||
const own = computed(() => isOwnNote(props.note));
|
||||
const editable = computed(() => canEditText(props.note));
|
||||
const canShare = computed(() => own.value && !isDesktop());
|
||||
const canShare = own;
|
||||
const sharedLine = computed(() => {
|
||||
if (!own.value) {
|
||||
const who = props.note.shared_by?.display_name || "someone";
|
||||
|
||||
@@ -13,7 +13,6 @@ import type { Note, NoteLabel, NoteRevision } from "../stores/notes";
|
||||
import { labelChipClasses } from "../notes/colors";
|
||||
import { canEditText, isOwnNote } from "../notes/sharing";
|
||||
import { useUiStore } from "../stores/ui";
|
||||
import { isDesktop } from "../desktop/bridge";
|
||||
import {
|
||||
afterEnter,
|
||||
type EditorBlock,
|
||||
@@ -123,7 +122,9 @@ const bodyPlaceholder = "Take a note…";
|
||||
const ui = useUiStore();
|
||||
const own = computed(() => isOwnNote(liveNote.value));
|
||||
const editable = computed(() => canEditText(liveNote.value));
|
||||
const canShare = computed(() => own.value && !isCreate.value && !isDesktop());
|
||||
// On the desktop too: linked, it shares through the server; unlinked, the dialog
|
||||
// says sharing needs one (#5175).
|
||||
const canShare = computed(() => own.value && !isCreate.value);
|
||||
const sharedLine = computed(() => {
|
||||
if (own.value) return "";
|
||||
const who = liveNote.value.shared_by?.display_name || "someone";
|
||||
|
||||
Reference in New Issue
Block a user