mirror of
https://github.com/wassname/talk.git
synced 2026-09-10 12:43:11 +08:00
Implement and use pymStorage
This commit is contained in:
@@ -92,12 +92,6 @@ const singleCommentFragment = gql`
|
||||
const withCommentFragments = withFragments({
|
||||
root: gql`
|
||||
fragment CoralEmbedStream_Comment_root on RootQuery {
|
||||
me {
|
||||
ignoredUsers {
|
||||
id
|
||||
}
|
||||
}
|
||||
__typename
|
||||
me {
|
||||
ignoredUsers {
|
||||
id
|
||||
|
||||
@@ -3,6 +3,7 @@ import pym from 'pym.js';
|
||||
import EventEmitter from 'eventemitter2';
|
||||
import {buildUrl} from 'coral-framework/utils/url';
|
||||
import Snackbar from './Snackbar';
|
||||
import {createStorage, connectStorageToPym} from 'coral-framework/services/storage';
|
||||
|
||||
const NOTIFICATION_OFFSET = 200;
|
||||
|
||||
@@ -134,6 +135,9 @@ export default class Stream {
|
||||
|
||||
// If the user clicks outside the embed, then tell the embed.
|
||||
document.addEventListener('click', this.handleClick.bind(this), true);
|
||||
|
||||
// Listens to storage requests on pym and relay it to local storage.
|
||||
connectStorageToPym(createStorage(), this.pym);
|
||||
}
|
||||
|
||||
login(token) {
|
||||
|
||||
@@ -83,7 +83,7 @@ Talk.render = (el, opts) => {
|
||||
console.warn(
|
||||
'This page does not include a canonical link tag. Talk has inferred this asset_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages.'
|
||||
);
|
||||
|
||||
|
||||
if (!window.location.origin) {
|
||||
window.location.origin = `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`;
|
||||
}
|
||||
|
||||
+3
-1
@@ -12,7 +12,7 @@ import {createPluginsService} from './plugins';
|
||||
import {createNotificationService} from './notification';
|
||||
import {createGraphQLRegistry} from './graphqlRegistry';
|
||||
import globalFragments from 'coral-framework/graphql/fragments';
|
||||
import {createStorage} from 'coral-framework/services/storage';
|
||||
import {createStorage, createPymStorage} from 'coral-framework/services/storage';
|
||||
import {createHistory} from 'coral-framework/services/history';
|
||||
import {createIntrospection} from 'coral-framework/services/introspection';
|
||||
import introspectionData from 'coral-framework/graphql/introspection.json';
|
||||
@@ -81,6 +81,7 @@ export async function createContext({
|
||||
} = {}) {
|
||||
const eventEmitter = new EventEmitter({wildcard: true});
|
||||
const storage = createStorage();
|
||||
const pymStorage = createPymStorage(pym);
|
||||
const history = createHistory(BASE_PATH);
|
||||
const introspection = createIntrospection(introspectionData);
|
||||
let store = null;
|
||||
@@ -137,6 +138,7 @@ export async function createContext({
|
||||
storage,
|
||||
history,
|
||||
introspection,
|
||||
pymStorage,
|
||||
};
|
||||
|
||||
// Load framework fragments.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import uuid from 'uuid/v4';
|
||||
|
||||
function getStorage(type) {
|
||||
let storage = window[type], x = '__storage_test__';
|
||||
@@ -41,3 +42,90 @@ function getStorage(type) {
|
||||
export function createStorage() {
|
||||
return getStorage('localStorage');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a storage that relay requests over to pym.
|
||||
* This is the counterpart of `connectStorageToPym`.
|
||||
* @param {string} pym pym
|
||||
* @return {Object} storage
|
||||
*/
|
||||
export function createPymStorage(pym) {
|
||||
|
||||
// A Map of requestID => {resolve, reject}
|
||||
const requests = {};
|
||||
|
||||
// Requests method with parameters over pym.
|
||||
const call = (method, parameters) => {
|
||||
const id = uuid();
|
||||
return new Promise((resolve, reject) => {
|
||||
requests[id] = {resolve, reject};
|
||||
pym.sendMessage('pymStorage.request', JSON.stringify({id, method, parameters}));
|
||||
});
|
||||
};
|
||||
|
||||
// Receive successful responses.
|
||||
pym.onMessage('pymStorage.response', (msg) => {
|
||||
const {id, result} = JSON.parse(msg);
|
||||
requests[id].resolve(result);
|
||||
delete requests[id];
|
||||
});
|
||||
|
||||
// Receive error responses.
|
||||
pym.onMessage('pymStorage.error', (msg) => {
|
||||
const {id, error} = JSON.parse(msg);
|
||||
requests[id].reject(error);
|
||||
delete requests[id];
|
||||
});
|
||||
|
||||
return {
|
||||
setItem: (key, value) => call('setItem', {key, value}),
|
||||
getItem: (key, value) => call('getItem', {key, value}),
|
||||
removeItem: (key) => call('removeItem', {key}),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to `pym` and relay storage requests to `storage`.
|
||||
* This is the counterpart of `createPymStorage`.
|
||||
* @param {string} pym pym
|
||||
* @return {Object} storage
|
||||
*/
|
||||
export function connectStorageToPym(storage, pym) {
|
||||
pym.onMessage('pymStorage.request', (msg) => {
|
||||
const {id, method, parameters} = JSON.parse(msg);
|
||||
const {key, value} = parameters;
|
||||
const prefixedKey = `talkPymStorage:${key}`;
|
||||
|
||||
// Variable for the method return value.
|
||||
let result;
|
||||
|
||||
const sendError = (error) => {
|
||||
console.error(error);
|
||||
pym.sendMessage('pymStorage.error', JSON.stringify({id, error}));
|
||||
};
|
||||
|
||||
try {
|
||||
switch(method) {
|
||||
case 'setItem':
|
||||
result = storage.setItem(prefixedKey, value);
|
||||
break;
|
||||
case 'getItem':
|
||||
result = storage.getItem(prefixedKey);
|
||||
break;
|
||||
case 'removeItem':
|
||||
result = storage.removeItem(prefixedKey);
|
||||
break;
|
||||
default:
|
||||
sendError(`Unknown method ${method}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
sendError(err.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
pym.sendMessage('pymStorage.response', JSON.stringify({id, result}));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import {sortOrderSelector, sortBySelector} from 'plugin-api/beta/client/selector
|
||||
const STORAGE_PATH = 'talkPluginRememberSort';
|
||||
|
||||
export default {
|
||||
init: ({store, storage, introspection}) => {
|
||||
init: async ({store, pymStorage, introspection}) => {
|
||||
|
||||
// TODO: workaround as this plugin is included in any target and
|
||||
// embeds (e.g. admin), but should only be included inside the stream.
|
||||
@@ -14,7 +14,10 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
let sort = JSON.parse(storage.getItem(STORAGE_PATH));
|
||||
// We use pymStorage instead to persist the data directly on the parent page,
|
||||
// in order to mitigate strict cross domain security settings.
|
||||
|
||||
let sort = JSON.parse(await pymStorage.getItem(STORAGE_PATH));
|
||||
if (
|
||||
sort &&
|
||||
introspection.isValidEnumValue('SORT_ORDER', sort.sortOrder) &&
|
||||
@@ -30,7 +33,7 @@ export default {
|
||||
// Save sorting choice to storage if it has changed.
|
||||
if (!sort || sort.sortOrder !== sortOrder || sort.sortBy !== sortBy) {
|
||||
sort = {sortOrder, sortBy};
|
||||
storage.setItem(STORAGE_PATH, JSON.stringify(sort));
|
||||
pymStorage.setItem(STORAGE_PATH, JSON.stringify(sort));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user