diff --git a/README.md b/README.md index 21acb79c..8587a1cd 100644 --- a/README.md +++ b/README.md @@ -463,10 +463,12 @@ Add this snippet to the bottom of web page: theme: 'dark', // optional param; if it isn't defined default value ('light') will be used page_title: 'Moving to Remark42', // optional param; if it isn't defined `document.title` will be used locale: 'en', // set up locale and language, if it isn't defined default value ('en') will be used - show_email_subscription: false // optional param; by default it is `true` and you can see email subscription feature - // in interface when enable it from backend side - // if you set this param in `false` you will get notifications email notifications as admin - // but your users won't have interface for subscription + show_email_subscription: false, // optional param; by default it is `true` and you can see email subscription feature + // in interface when enable it from backend side + // if you set this param in `false` you will get notifications email notifications as admin + // but your users won't have interface for subscription + simple_view: false // optional param; overrides the parameter from the backend + // minimized UI with basic info only }; diff --git a/frontend/app/remark.tsx b/frontend/app/remark.tsx index 29831b8e..d3339bba 100644 --- a/frontend/app/remark.tsx +++ b/frontend/app/remark.tsx @@ -14,6 +14,7 @@ import { getConfig } from 'common/api'; import { fetchHiddenUsers } from 'store/user/actions'; import { restoreCollapsedThreads } from 'store/thread/actions'; import parseQuery from 'utils/parseQuery'; +import { parseBooleansFromDictionary } from 'utils/parse-booleans-from-dictionary'; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); @@ -30,7 +31,7 @@ async function init(): Promise { throw new Error("Remark42: Can't find root node."); } - const params = parseQuery<{ page?: string; locale?: string }>(); + const params = parseQuery<{ page?: string; locale?: string; simple_view?: boolean }>(); const locale = getLocale(params); const messages = await loadLocale(locale).catch(() => ({})); const boundActions = bindActionCreators({ fetchHiddenUsers, restoreCollapsedThreads }, reduxStore.dispatch); @@ -38,7 +39,9 @@ async function init(): Promise { boundActions.fetchHiddenUsers(); boundActions.restoreCollapsedThreads(); - StaticStore.config = await getConfig(); + const config = await getConfig(); + const optionsParams = parseBooleansFromDictionary(params, 'simple_view'); + StaticStore.config = { ...config, ...optionsParams }; render( diff --git a/frontend/app/typings/global.d.ts b/frontend/app/typings/global.d.ts index 3c469218..8f0ae214 100644 --- a/frontend/app/typings/global.d.ts +++ b/frontend/app/typings/global.d.ts @@ -12,6 +12,7 @@ type RemarkConfig = { show_email_subscription?: boolean; max_last_comments?: number; __colors__?: Record; + simple_view?: boolean; }; declare global { diff --git a/frontend/app/utils/parse-booleans-from-dictionary.test.ts b/frontend/app/utils/parse-booleans-from-dictionary.test.ts new file mode 100644 index 00000000..5bf537bc --- /dev/null +++ b/frontend/app/utils/parse-booleans-from-dictionary.test.ts @@ -0,0 +1,57 @@ +import { parseBooleansFromDictionary } from './parse-booleans-from-dictionary'; + +const defaultProps = { + components: 'embed,counter', + host: 'http://127.0.0.1:9000', + locale: 'ru', + site_id: 'remark', + theme: 'dark', +}; + +describe('getConfigMerge', () => { + it('when we need to get one field and it is "true"', () => { + const params = { + ...defaultProps, + simple: 'true', + simple_view: 'true', + }; + expect(parseBooleansFromDictionary(params, 'simple_view')).toEqual({ simple_view: true }); + }); + + it('when we need to get one field and it is "false"', () => { + const params = { + ...defaultProps, + simple: 'true', + simple_view: 'false', + }; + expect(parseBooleansFromDictionary(params, 'simple_view')).toEqual({ simple_view: false }); + }); + it('when we need to get one or more fields', () => { + const params = { + ...defaultProps, + simple: 'false', + simple_view: 'true', + }; + expect(parseBooleansFromDictionary(params, 'simple_view', 'simple')).toEqual({ + simple: false, + simple_view: true, + }); + }); + + it('when the required field does not exist', () => { + const params = { + ...defaultProps, + simple: 'true', + }; + expect(parseBooleansFromDictionary(params, 'simple_view')).toEqual({}); + }); + + it('when the field has the wrong format', () => { + const params = { + ...defaultProps, + simple: 'true', + simple_view: 'dark', + }; + expect(parseBooleansFromDictionary(params, 'simple_view', 'simple')).toEqual({ simple: true }); + }); +}); diff --git a/frontend/app/utils/parse-booleans-from-dictionary.ts b/frontend/app/utils/parse-booleans-from-dictionary.ts new file mode 100644 index 00000000..e52f9c4c --- /dev/null +++ b/frontend/app/utils/parse-booleans-from-dictionary.ts @@ -0,0 +1,15 @@ +export function parseBooleansFromDictionary(input: Record, ...args: string[]) { + const result: Record = {}; + for (let key of args) { + if (input[key] === undefined) { + continue; + } + if (input[key] === 'true') { + result[key] = true; + } + if (input[key] === 'false') { + result[key] = false; + } + } + return result; +} diff --git a/frontend/app/utils/parseQuery.ts b/frontend/app/utils/parseQuery.ts index efdbd703..0f378a1e 100644 --- a/frontend/app/utils/parseQuery.ts +++ b/frontend/app/utils/parseQuery.ts @@ -1,4 +1,4 @@ -/** converts widnow.location.search into object */ +/** converts window.location.search into object */ export default function parseQuery(search: string = window.location.search): T { const params: { [key: string]: string } = {}; diff --git a/frontend/templates/demo.ejs b/frontend/templates/demo.ejs index 707e62aa..2b970ce3 100644 --- a/frontend/templates/demo.ejs +++ b/frontend/templates/demo.ejs @@ -129,8 +129,9 @@ // __colors__: { // "--color0": "red", // }, - theme: theme - // locale: "ru" + theme: theme, + // locale: "ru", + // simple_view: true, }; (function (c, d) { @@ -143,7 +144,7 @@ s.type = 'module'; e = '.mjs'; } - + s.async = true; s.defer = true; s.src = remark_config.host + '/web/' + c[i] + e;