diff --git a/scripts/patch_mobile_realtime.py b/scripts/patch_mobile_realtime.py new file mode 100644 index 0000000..35642a4 --- /dev/null +++ b/scripts/patch_mobile_realtime.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +""" +Patch MobileTicketAgent.vue to add socket realtime listeners so that +comments and ticket updates auto-reload without a manual refresh. +Mirrors the onMounted/onUnmounted logic from TicketAgent.vue. +""" + +TARGET = '/home/frappe/frappe-bench/frappe-bench/apps/helpdesk/desk/src/pages/ticket/MobileTicketAgent.vue' + +with open(TARGET, 'r') as f: + content = f.read() + +# ── 1. Add globalStore import ──────────────────────────────────────────────── +OLD_ROUTER = 'import { useRouter } from "vue-router";' +NEW_ROUTER = '''import { useRouter } from "vue-router"; +import { globalStore } from "@/stores/globalStore";''' + +assert OLD_ROUTER in content, 'ERROR: router import anchor not found' +content = content.replace(OLD_ROUTER, NEW_ROUTER, 1) + +# ── 2. Add $socket destructure near top of setup (after router/store inits) ─ +OLD_STORE_INIT = 'const ticketStatusStore = useTicketStatusStore();\nconst { getUser } = useUserStore();' +NEW_STORE_INIT = '''const ticketStatusStore = useTicketStatusStore(); +const { getUser } = useUserStore(); +const { $socket } = globalStore();''' + +assert OLD_STORE_INIT in content, 'ERROR: store init anchor not found' +content = content.replace(OLD_STORE_INIT, NEW_STORE_INIT, 1) + +# ── 3. Patch onMounted to add socket listeners ─────────────────────────────── +OLD_MOUNTED = '''onMounted(() => { + document.title = props.ticketId; +});''' + +NEW_MOUNTED = '''onMounted(() => { + document.title = props.ticketId; + + // BMG: realtime — reload activities when a new comment is posted + $socket.on("helpdesk:ticket-comment", (data: { ticket_id: string }) => { + if (String(data.ticket_id) === String(props.ticketId)) { + ticket.reload(); + } + }); + + // BMG: realtime — reload ticket when it is updated by another user + $socket.on("helpdesk:ticket-update", (data: { ticket_id: string }) => { + if (String(data.ticket_id) === String(props.ticketId)) { + ticket.reload(); + } + }); +});''' + +assert OLD_MOUNTED in content, 'ERROR: onMounted anchor not found' +content = content.replace(OLD_MOUNTED, NEW_MOUNTED, 1) + +# ── 4. Patch onUnmounted to remove socket listeners ───────────────────────── +OLD_UNMOUNTED = '''onUnmounted(() => { + document.title = "Helpdesk"; +});''' + +NEW_UNMOUNTED = '''onUnmounted(() => { + document.title = "Helpdesk"; + $socket.off("helpdesk:ticket-comment"); + $socket.off("helpdesk:ticket-update"); +});''' + +assert OLD_UNMOUNTED in content, 'ERROR: onUnmounted anchor not found' +content = content.replace(OLD_UNMOUNTED, NEW_UNMOUNTED, 1) + +with open(TARGET, 'w') as f: + f.write(content) + +print('PATCH OK')