sync form
This commit is contained in:
parent
1a2647a7b8
commit
d9ca5e3102
3 changed files with 53 additions and 23 deletions
|
@ -1,13 +1,13 @@
|
|||
import { defineStore } from "pinia";
|
||||
import { useConnectionStore } from "./connection";
|
||||
import * as Y from "yjs";
|
||||
import { Awareness } from "y-protocols/awareness.js";
|
||||
import { computed, ref } from "vue";
|
||||
import * as AwarenessProtocol from "y-protocols/awareness.js";
|
||||
|
||||
export const useMissionDetailStore = defineStore("missionDetail", {
|
||||
state: () => {
|
||||
return {
|
||||
yDoc: new Y.Doc(),
|
||||
awareness: undefined as undefined | AwarenessProtocol.Awareness,
|
||||
docId: null as null | string,
|
||||
lastUpdateTimestamp: 0 as number,
|
||||
connectionStatus: "disconnected", // 'disconnected', 'connecting', 'connected', 'syncing', 'synced'
|
||||
|
@ -18,16 +18,18 @@ export const useMissionDetailStore = defineStore("missionDetail", {
|
|||
this.docId = docId;
|
||||
|
||||
this.lastUpdateTimestamp = this.loadLastUpdateFromLocalStorage();
|
||||
this.awareness = new AwarenessProtocol.Awareness(this.yDoc);
|
||||
this.awareness.setLocalStateField("user", { name: "hi", color: "#123456" });
|
||||
|
||||
this.setupSocketHandlers();
|
||||
this.setupYjsObservers();
|
||||
this.setupAwarenessObservers();
|
||||
},
|
||||
|
||||
setupSocketHandlers() {
|
||||
const connectionStore = useConnectionStore();
|
||||
if (!connectionStore.connection) return;
|
||||
|
||||
connectionStore.connection.on("package-sync", (data) => {
|
||||
connectionStore.connection?.on("package-sync", (data) => {
|
||||
try {
|
||||
this.connectionStatus = "syncing";
|
||||
|
||||
|
@ -44,7 +46,7 @@ export const useMissionDetailStore = defineStore("missionDetail", {
|
|||
this.requestFullSync();
|
||||
}
|
||||
});
|
||||
connectionStore.connection.on("sync-get-missing-updates", (data) => {
|
||||
connectionStore.connection?.on("sync-get-missing-updates", (data) => {
|
||||
const clientUpdates = Y.encodeStateAsUpdate(this.yDoc, new Uint8Array(data.stateVector));
|
||||
|
||||
connectionStore.connection?.emit("mission:sync-client-updates", {
|
||||
|
@ -53,12 +55,16 @@ export const useMissionDetailStore = defineStore("missionDetail", {
|
|||
});
|
||||
});
|
||||
|
||||
connectionStore.connection?.on("package-sync-awareness", (data) => {
|
||||
// if (this.awareness != undefined) {
|
||||
// AwarenessProtocol.applyAwarenessUpdate(this.awareness, new Uint8Array(data.update), this);
|
||||
// }
|
||||
});
|
||||
|
||||
this.joinDocument();
|
||||
},
|
||||
|
||||
setupYjsObservers() {
|
||||
if (!this.yDoc) return;
|
||||
|
||||
this.yDoc.on("update", (update) => {
|
||||
const connectionStore = useConnectionStore();
|
||||
if (connectionStore.connected) {
|
||||
|
@ -73,20 +79,35 @@ export const useMissionDetailStore = defineStore("missionDetail", {
|
|||
});
|
||||
},
|
||||
|
||||
joinDocument() {
|
||||
const connectionStore = useConnectionStore();
|
||||
if (!connectionStore.connection || !this.docId) return;
|
||||
setupAwarenessObservers() {
|
||||
if (!this.awareness) return;
|
||||
|
||||
connectionStore.connection.emit("mission:join", this.docId, {
|
||||
this.awareness.on("update", (update: { added: number[]; updated: number[]; removed: number[] }) => {
|
||||
if (this.awareness != undefined) {
|
||||
const changedClients = update.added.concat(update.updated).concat(update.removed);
|
||||
const connectionStore = useConnectionStore();
|
||||
connectionStore.connection?.emit(
|
||||
"mission:sync-client-awareness",
|
||||
Array.from(AwarenessProtocol.encodeAwarenessUpdate(this.awareness, changedClients))
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
joinDocument() {
|
||||
if (!this.docId) return;
|
||||
|
||||
const connectionStore = useConnectionStore();
|
||||
connectionStore.connection?.emit("mission:join", this.docId, {
|
||||
timestamp: this.lastUpdateTimestamp,
|
||||
});
|
||||
},
|
||||
|
||||
requestFullSync() {
|
||||
const connectionStore = useConnectionStore();
|
||||
if (!connectionStore.connection || !this.docId) return;
|
||||
if (!this.docId) return;
|
||||
|
||||
connectionStore.connection.emit("mission:join", this.docId, null);
|
||||
const connectionStore = useConnectionStore();
|
||||
connectionStore.connection?.emit("mission:join", this.docId, null);
|
||||
},
|
||||
|
||||
loadLastUpdateFromLocalStorage() {
|
||||
|
@ -97,16 +118,18 @@ export const useMissionDetailStore = defineStore("missionDetail", {
|
|||
},
|
||||
|
||||
saveLastUpdateToLocalStorage() {
|
||||
if (!this.docId) return;
|
||||
|
||||
localStorage.setItem(`yjsDoc_timestamp`, this.lastUpdateTimestamp.toString());
|
||||
},
|
||||
|
||||
cleanup() {
|
||||
if (this.yDoc) {
|
||||
this.yDoc.destroy();
|
||||
this.yDoc = new Y.Doc();
|
||||
if (this.awareness) {
|
||||
AwarenessProtocol.removeAwarenessStates(this.awareness, [this.yDoc.clientID], "window unload");
|
||||
this.awareness.destroy();
|
||||
}
|
||||
|
||||
this.yDoc.destroy();
|
||||
this.yDoc = new Y.Doc();
|
||||
|
||||
this.lastUpdateTimestamp = 0;
|
||||
localStorage.removeItem("yjsDoc_timestamp");
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
:style="!can('create', 'operation', 'mission') ? 'opacity: 75%; background: rgb(243 244 246)' : ''"
|
||||
@ready="initEditor"
|
||||
/>
|
||||
<!--v-model:content=""-->
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<p>Eingesetzte Fahrzeuge</p>
|
||||
|
@ -86,6 +85,7 @@ import { moduleOptions } from "@/helpers/quillConfig";
|
|||
import ForceSelect from "@/components/admin/ForceSelect.vue";
|
||||
import { useForceStore } from "@/stores/admin/configuration/force";
|
||||
import * as Y from "yjs";
|
||||
import type { Awareness } from "y-protocols/awareness.js";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
|
@ -95,6 +95,10 @@ export default defineComponent({
|
|||
type: Object as PropType<Y.Doc>,
|
||||
required: true,
|
||||
},
|
||||
awareness: {
|
||||
type: Object as PropType<Awareness | undefined>,
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -126,7 +130,7 @@ export default defineComponent({
|
|||
methods: {
|
||||
initEditor(quill: Quill) {
|
||||
quill.history.clear();
|
||||
this.binding = new QuillBinding(this.editor, quill);
|
||||
this.binding = new QuillBinding(this.editor, quill, this.awareness);
|
||||
this.cursors = quill.getModule("cursors") as QuillCursors;
|
||||
},
|
||||
},
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<MissionDetail v-show="routeHash == '#edit'" :document="yDoc" />
|
||||
<MissionDetail v-show="routeHash == '#edit'" :document="yDoc" :awareness="awareness" />
|
||||
<MissionPresence v-show="routeHash == '#presence'" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -77,10 +77,13 @@ export default defineComponent({
|
|||
},
|
||||
computed: {
|
||||
...mapState(useConnectionStore, ["connectionStatus"]),
|
||||
...mapWritableState(useMissionDetailStore, ["yDoc"]),
|
||||
...mapWritableState(useMissionDetailStore, ["yDoc", "awareness"]),
|
||||
routeHash() {
|
||||
return this.$route.hash;
|
||||
},
|
||||
editors() {
|
||||
return this.awareness?.getStates() ?? [];
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.manageHash();
|
||||
|
|
Loading…
Add table
Reference in a new issue