Skip to content

Commit

Permalink
Experimental support for runtime custom emotes (#2669)
Browse files Browse the repository at this point in the history
  • Loading branch information
goto-bus-stop authored Mar 8, 2023
1 parent 09821f9 commit fda7552
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/Uwave.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { loadCurrentLanguage } from './actions/LocaleActionCreators';
* @typedef {object} UwaveOptions
* @prop {string} [apiBase]
* @prop {string} [socketUrl]
* @prop {Record<string, string>} [emoji]
* @prop {{ name: string, url: string }[]} [serverEmotes]
*/

export default class Uwave {
Expand Down
13 changes: 12 additions & 1 deletion src/actions/ChatActionCreators.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import {
REMOVE_ALL_MESSAGES,
MUTE_USER,
UNMUTE_USER,
LOAD_EMOTES,
} from '../constants/ActionTypes';
import { put } from './RequestActionCreators';
import { get, put } from './RequestActionCreators';
import {
muteTimeoutsSelector,
mutedUserIDsSelector,
Expand Down Expand Up @@ -222,3 +223,13 @@ export function setMotd(text) {
}),
});
}

export function loadEmotes() {
return async (dispatch) => {
const emotes = await dispatch(get('/emotes'));
dispatch({
type: LOAD_EMOTES,
payload: { emotes: emotes.data },
});
};
}
2 changes: 2 additions & 0 deletions src/actions/LoginActionCreators.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { loadHistory } from './BoothActionCreators';
import { setPlaylists, loadPlaylist } from './PlaylistActionCreators';
import { syncTimestamps } from './TickerActionCreators';
import { closeLoginDialog } from './DialogActionCreators';
import { loadEmotes } from './ChatActionCreators';
import { tokenSelector } from '../selectors/userSelectors';

export function socketConnect() {
Expand Down Expand Up @@ -79,6 +80,7 @@ export function initState() {
dispatch(syncTimestamps(beforeTime, state.time));
dispatch(loadedState(state));
dispatch(loadHistory());
dispatch(loadEmotes());
return state;
},
});
Expand Down
1 change: 1 addition & 0 deletions src/constants/ActionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from './actionTypes/time';
export * from './actionTypes/users';
export * from './actionTypes/votes';
export * from './actionTypes/waitlist';
export const LOAD_EMOTES = 'emotes/LOAD';
13 changes: 11 additions & 2 deletions src/reducers/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { INIT_STATE } from '../constants/ActionTypes';
import { INIT_STATE, LOAD_EMOTES } from '../constants/ActionTypes';

const initialState = {};
export const initialState = {
roles: undefined,
emoji: {},
serverEmotes: [],
};

export default function reduce(state = initialState, action = {}) {
const { type, payload } = action;
Expand All @@ -13,6 +17,11 @@ export default function reduce(state = initialState, action = {}) {
};
}
return state;
case LOAD_EMOTES:
return {
...state,
serverEmotes: payload.emotes,
};
default:
return state;
}
Expand Down
2 changes: 2 additions & 0 deletions src/redux/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
removeAllMessages,
muteUser as chatMute,
unmuteUser as chatUnmute,
loadEmotes,
} from '../actions/ChatActionCreators';
import { cyclePlaylist } from '../actions/PlaylistActionCreators';
import {
Expand Down Expand Up @@ -129,6 +130,7 @@ const actions = {
guests: receiveGuestCount,
'acl:allow': ({ userID, roles }) => addUserRoles(userID, roles),
'acl:disallow': ({ userID, roles }) => removeUserRoles(userID, roles),
reloadEmotes: loadEmotes,
};

// WebSocket wrapper with reconnection and message parsing.
Expand Down
11 changes: 10 additions & 1 deletion src/selectors/configSelectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ export const requestOptionsSelector = createSelector(

export const availableEmojiImagesSelector = createSelector(
configSelector,
(config) => ({ ...defaultEmoji, ...config.emoji }),
(config) => {
const serverEmotes = config.serverEmotes.map(({ name, url }) => [name, url]);
return {
...defaultEmoji,
...config.emoji,
...Object.fromEntries(serverEmotes),
};
},
);

export const availableEmojiNamesSelector = createSelector(
Expand All @@ -26,6 +33,8 @@ export const availableEmojiNamesSelector = createSelector(

// This is slightly hacky: custom emoji will be hosted on
// a different URL so we have to mark them.
// Note server emotes do not need to be added here as they
// use full URLs.
// TODO(goto-bus-stop) I think builtins and custom emoji
// should be separated entirely so that we can interpret
// unicode emoji as builtin ones.
Expand Down
12 changes: 9 additions & 3 deletions src/utils/readApplicationConfig.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { initialState } from '../reducers/config';

export default function readApplicationConfig(container = '#u-wave-config') {
const config = { ...initialState };

try {
return JSON.parse(document.querySelector(container).textContent);
} catch (e) {
return {};
Object.assign(config, JSON.parse(document.querySelector(container).textContent));
} catch {
// ignore
}

return config;
}

0 comments on commit fda7552

Please sign in to comment.