Skip to content

Commit

Permalink
Feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
corrideat committed Nov 29, 2024
1 parent 37ab10b commit c5232e1
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 96 deletions.
85 changes: 68 additions & 17 deletions frontend/controller/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
import sbp from '@sbp/sbp'
import { CAPTURED_LOGS, LOGIN_COMPLETE, NEW_CHATROOM_UNREAD_POSITION, PWA_INSTALLABLE, SET_APP_LOGS_FILTER } from '@utils/events.js'
import { HOURS_MILLIS } from '~/frontend/model/contracts/shared/time.js'
import { deserializer } from '~/shared/serdes/index.js'
import { GIMessage } from '~/shared/domains/chelonia/GIMessage.js'
import { Secret } from '~/shared/domains/chelonia/Secret.js'
import { deserializer, serializer } from '~/shared/serdes/index.js'
import { ONLINE } from '../utils/events.js'

const pwa = {
deferredInstallPrompt: null,
installed: false
}

deserializer.register(GIMessage)
deserializer.register(Secret)

// How to provide your own in-app PWA install experience:
// https://web.dev/articles/customize-install

Expand Down Expand Up @@ -169,21 +174,67 @@ sbp('sbp/selectors/register', {
})
)

// helper method
/*
function urlBase64ToUint8Array (base64String) {
// reference: https://gist.github.com/Klerith/80abd742d726dd587f4bd5d6a0ab26b6
const padding = '='.repeat((4 - (base64String.length % 4)) % 4)
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/')
const rawData = atob(base64)
const outputArray = new Uint8Array(rawData.length)
const swRpc = (() => {
if (!navigator.serviceWorker) {
throw new Error('Missing service worker object')
}
let controller: ?ServiceWorker = navigator.serviceWorker.controller
navigator.serviceWorker.addEventListener('controllerchange', (ev: Event) => {
controller = (navigator.serviceWorker: any).controller
}, false)

return (...args) => {
return new Promise((resolve, reject) => {
if (!controller) {
reject(new Error('Service worker not ready'))
return
}
const messageChannel = new MessageChannel()
messageChannel.port1.addEventListener('message', (event: MessageEvent) => {
if (event.data && Array.isArray(event.data)) {
const r = deserializer(event.data[1])
// $FlowFixMe[incompatible-use]
if (event.data[0] === true) {
resolve(r)
} else {
reject(r)
}
messageChannel.port1.close()
}
}, false)
messageChannel.port1.addEventListener('messageerror', (event: MessageEvent) => {
reject(event.data)
messageChannel.port1.close()
}, false)
messageChannel.port1.start()
const { data, transferables } = serializer(args)
controller.postMessage({
type: 'sbp',
port: messageChannel.port2,
data
}, [messageChannel.port2, ...transferables])
})
}
})()

for (let i = 0; i < rawData.length; i++) {
outputArray[i] = rawData.charCodeAt(i)
sbp('sbp/selectors/register', {
'gi.actions/*': swRpc
})
sbp('sbp/selectors/register', {
'chelonia/*': swRpc
})
sbp('sbp/selectors/register', {
'sw-namespace/*': (...args) => {
// Remove the `sw-` prefix from the selector
return swRpc(args[0].slice(3), ...args.slice(1))
}
return outputArray
}
*/
})
sbp('sbp/selectors/register', {
'gi.notifications/*': swRpc
})
sbp('sbp/selectors/register', {
'swLogs/*': swRpc
})
sbp('sbp/selectors/register', {
'push/*': swRpc
})
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

import sbp from '@sbp/sbp'
import { NAMESPACE_REGISTRATION } from '../utils/events.js'
import { NAMESPACE_REGISTRATION } from '@utils/events.js'

// NOTE: prefix groups with `group/` and users with `user/` ?
sbp('sbp/selectors/register', {
Expand Down
25 changes: 21 additions & 4 deletions frontend/controller/serviceworkers/sw-primary.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import '@sbp/okturtles.eventqueue'
import '@sbp/okturtles.events'
import sbp from '@sbp/sbp'
import '~/frontend/controller/actions/index.js'
import '~/frontend/controller/sw-namespace.js'
import './sw-namespace.js'
import chatroomGetters from '~/frontend/model/chatroom/getters.js'
import getters from '~/frontend/model/getters.js'
import '~/frontend/model/notifications/selectors.js'
Expand All @@ -18,7 +18,14 @@ import { GIMessage } from '~/shared/domains/chelonia/GIMessage.js'
import { Secret } from '~/shared/domains/chelonia/Secret.js'
import { CHELONIA_RESET, CONTRACTS_MODIFIED, CONTRACT_IS_SYNCING, EVENT_HANDLED } from '~/shared/domains/chelonia/events.js'
import { deserializer, serializer } from '~/shared/serdes/index.js'
import { ACCEPTED_GROUP, CAPTURED_LOGS, CHATROOM_USER_STOP_TYPING, CHATROOM_USER_TYPING, DELETED_CHATROOM, JOINED_CHATROOM, JOINED_GROUP, KV_EVENT, LEFT_CHATROOM, LEFT_GROUP, NAMESPACE_REGISTRATION, NEW_CHATROOM_UNREAD_POSITION, NEW_LAST_LOGGED_IN, NEW_PREFERENCES, NEW_UNREAD_MESSAGES, NOTIFICATION_EMITTED, NOTIFICATION_REMOVED, NOTIFICATION_STATUS_LOADED, OFFLINE, ONLINE, SERIOUS_ERROR, SWITCH_GROUP } from '../../utils/events.js'
import {
ACCEPTED_GROUP, CAPTURED_LOGS, CHATROOM_USER_STOP_TYPING,
CHATROOM_USER_TYPING, DELETED_CHATROOM, JOINED_CHATROOM, JOINED_GROUP,
KV_EVENT, LEFT_CHATROOM, LEFT_GROUP, NAMESPACE_REGISTRATION,
NEW_CHATROOM_UNREAD_POSITION, NEW_LAST_LOGGED_IN, NEW_PREFERENCES,
NEW_UNREAD_MESSAGES, NOTIFICATION_EMITTED, NOTIFICATION_REMOVED,
NOTIFICATION_STATUS_LOADED, OFFLINE, ONLINE, SERIOUS_ERROR, SWITCH_GROUP
} from '../../utils/events.js'
import './push.js'

deserializer.register(GIMessage)
Expand Down Expand Up @@ -54,9 +61,19 @@ const selectorBlacklist = [
sbp('sbp/filters/global/add', (domain, selector, data) => {
if (domainBlacklist[domain] || selectorBlacklist[selector]) return
console.debug(`[sbp] ${selector}`, data)
});
})

[CHELONIA_RESET, CONTRACTS_MODIFIED, CONTRACT_IS_SYNCING, EVENT_HANDLED, LOGIN, LOGIN_ERROR, LOGOUT, ACCEPTED_GROUP, CHATROOM_USER_STOP_TYPING, CHATROOM_USER_TYPING, DELETED_CHATROOM, LEFT_CHATROOM, LEFT_GROUP, JOINED_CHATROOM, JOINED_GROUP, KV_EVENT, MESSAGE_RECEIVE, MESSAGE_SEND, NAMESPACE_REGISTRATION, NEW_CHATROOM_UNREAD_POSITION, NEW_LAST_LOGGED_IN, NEW_PREFERENCES, NEW_UNREAD_MESSAGES, NOTIFICATION_EMITTED, NOTIFICATION_REMOVED, NOTIFICATION_STATUS_LOADED, OFFLINE, ONLINE, PROPOSAL_ARCHIVED, SERIOUS_ERROR, SWITCH_GROUP].forEach(et => {
// These are all of the events that will be forwarded to all open tabs and windows
;[
CHELONIA_RESET, CONTRACTS_MODIFIED, CONTRACT_IS_SYNCING, EVENT_HANDLED, LOGIN,
LOGIN_ERROR, LOGOUT, ACCEPTED_GROUP, CHATROOM_USER_STOP_TYPING,
CHATROOM_USER_TYPING, DELETED_CHATROOM, LEFT_CHATROOM, LEFT_GROUP,
JOINED_CHATROOM, JOINED_GROUP, KV_EVENT, MESSAGE_RECEIVE, MESSAGE_SEND,
NAMESPACE_REGISTRATION, NEW_CHATROOM_UNREAD_POSITION, NEW_LAST_LOGGED_IN,
NEW_PREFERENCES, NEW_UNREAD_MESSAGES, NOTIFICATION_EMITTED,
NOTIFICATION_REMOVED, NOTIFICATION_STATUS_LOADED, OFFLINE, ONLINE,
PROPOSAL_ARCHIVED, SERIOUS_ERROR, SWITCH_GROUP
].forEach(et => {
sbp('okTurtles.events/on', et, (...args) => {
const { data } = serializer(args)
const message = {
Expand Down
77 changes: 3 additions & 74 deletions frontend/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ import './views/utils/ui.js'
import './views/utils/vError.js'
import './views/utils/vFocus.js'
// import './views/utils/vSafeHtml.js' // this gets imported by translations, which is part of common.js
import { GIMessage } from '~/shared/domains/chelonia/GIMessage.js'
import { Secret } from '~/shared/domains/chelonia/Secret.js'
import { deserializer, serializer } from '~/shared/serdes/index.js'
import Vue from 'vue'
import notificationsMixin from './model/notifications/mainNotificationsMixin.js'
import './model/notifications/periodicNotifications.js'
Expand All @@ -46,9 +43,6 @@ import './utils/touchInteractions.js'
import { showNavMixin } from './views/utils/misc.js'
import './views/utils/vStyle.js'

deserializer.register(GIMessage)
deserializer.register(Secret)

console.info('GI_VERSION:', process.env.GI_VERSION)
console.info('CONTRACTS_VERSION:', process.env.CONTRACTS_VERSION)
console.info('LIGHTWEIGHT_CLIENT:', process.env.LIGHTWEIGHT_CLIENT)
Expand Down Expand Up @@ -100,9 +94,9 @@ async function startApp () {
// Set up event listeners to keep local (Vuex) and Chelonia states in sync
sbp('chelonia/externalStateSetup', { stateSelector: 'state/vuex/state', reactiveSet: Vue.set, reactiveDel: Vue.delete })

// TODO: [SW] The following will be needed to keep namespace registrations
// in sync between the SW and each tab. It is not needed now because everything
// is running in the same context
// [SW] The following is be needed to keep namespace registrations in sync
// between the SW and each tab. It is not needed if everything is running in
// the same context
sbp('okTurtles.events/on', NAMESPACE_REGISTRATION, ({ name, value }) => {
const cache = sbp('state/vuex/state').namespaceLookups
const reverseCache = sbp('state/vuex/state').reverseNamespaceLookups
Expand Down Expand Up @@ -170,72 +164,7 @@ async function startApp () {
sbp('state/vuex/commit', 'setNotificationEnabled', Notification.permission === 'granted')
}

/* TODO: MOVE TO ANOTHER FILE */
sbp('okTurtles.data/set', 'API_URL', self.location.origin)
const swRpc = (() => {
if (!navigator.serviceWorker) {
throw new Error('Missing service worker object')
}
let controller: ?ServiceWorker = navigator.serviceWorker.controller
navigator.serviceWorker.addEventListener('controllerchange', (ev: Event) => {
controller = (navigator.serviceWorker: any).controller
}, false)

return (...args) => {
return new Promise((resolve, reject) => {
if (!controller) {
reject(new Error('Service worker not ready'))
return
}
const messageChannel = new MessageChannel()
messageChannel.port1.addEventListener('message', (event: MessageEvent) => {
if (event.data && Array.isArray(event.data)) {
const r = deserializer(event.data[1])
// $FlowFixMe[incompatible-use]
if (event.data[0] === true) {
resolve(r)
} else {
reject(r)
}
messageChannel.port1.close()
}
}, false)
messageChannel.port1.addEventListener('messageerror', (event: MessageEvent) => {
reject(event.data)
messageChannel.port1.close()
}, false)
messageChannel.port1.start()
const { data, transferables } = serializer(args)
controller.postMessage({
type: 'sbp',
port: messageChannel.port2,
data
}, [messageChannel.port2, ...transferables])
})
}
})()

sbp('sbp/selectors/register', {
'gi.actions/*': swRpc
})
sbp('sbp/selectors/register', {
'chelonia/*': swRpc
})
sbp('sbp/selectors/register', {
'sw-namespace/*': (...args) => {
// Remove the `sw-` prefix from the selector
return swRpc(args[0].slice(3), ...args.slice(1))
}
})
sbp('sbp/selectors/register', {
'gi.notifications/*': swRpc
})
sbp('sbp/selectors/register', {
'swLogs/*': swRpc
})
sbp('sbp/selectors/register', {
'push/*': swRpc
})

/* eslint-disable no-new */
new Vue({
Expand Down

0 comments on commit c5232e1

Please sign in to comment.