pl-fe: Actually do half of the url-purify lib code on pl-fe side lmao
Signed-off-by: mkljczk <git@mkljczk.pl>
This commit is contained in:
@ -64,7 +64,7 @@ const UrlPrivacy = () => {
|
||||
|
||||
<FormGroup
|
||||
labelText={<FormattedMessage id='url_privacy.rules_url.label' defaultMessage='URL cleaning rules database address' />}
|
||||
hintText={<FormattedMessage id='url_privacy.rules_url.placeholder' defaultMessage='Rules database in ClearURLs-compatible format, eg. {url}' values={{ url: 'https://rules2.clearurls.xyz/data.minify.json' }} />}
|
||||
hintText={<FormattedMessage id='url_privacy.rules_url.hint' defaultMessage='Rules database in ClearURLs-compatible format, eg. {url}' values={{ url: 'https://rules2.clearurls.xyz/data.minify.json' }} />}
|
||||
>
|
||||
<Input
|
||||
type='text'
|
||||
@ -76,7 +76,7 @@ const UrlPrivacy = () => {
|
||||
|
||||
<FormGroup
|
||||
labelText={<FormattedMessage id='url_privacy.hash_url.label' defaultMessage='URL cleaning rules hash address (optional)' />}
|
||||
hintText={<FormattedMessage id='url_privacy.hash_url.placeholder' defaultMessage='SHA256 hash of rules database, used to avoid unnecessary fetches, eg. {url}' values={{ url: 'https://rules2.clearurls.xyz/rules.minify.hash' }} />}
|
||||
hintText={<FormattedMessage id='url_privacy.hash_url.hint' defaultMessage='SHA256 hash of rules database, used to avoid unnecessary fetches, eg. {url}' values={{ url: 'https://rules2.clearurls.xyz/rules.minify.hash' }} />}
|
||||
>
|
||||
<Input
|
||||
type='text'
|
||||
|
||||
@ -1641,10 +1641,12 @@
|
||||
"url_privacy.allow_referral_marketing": "Make exception for referral marketing parameters",
|
||||
"url_privacy.clear_links_in_compose": "Suggest removing tracking parameters when composing a post",
|
||||
"url_privacy.clear_links_in_content": "Remove tracking parameters from displayed posts",
|
||||
"url_privacy.hash_url.hint": "SHA256 hash of rules database, used to avoid unnecessary fetches, eg. {url}",
|
||||
"url_privacy.hash_url.label": "URL cleaning rules hash address (optional)",
|
||||
"url_privacy.hash_url.placeholder": "SHA256 hash of rules database, used to avoid unnecessary fetches, eg. {url}",
|
||||
"url_privacy.hash_url.placeholder": "Hash URL",
|
||||
"url_privacy.rules_url.hint": "Rules database in ClearURLs-compatible format, eg. {url}",
|
||||
"url_privacy.rules_url.label": "URL cleaning rules database address",
|
||||
"url_privacy.rules_url.placeholder": "Rules database in ClearURLs-compatible format, eg. {url}",
|
||||
"url_privacy.rules_url.placeholder": "Rules URL",
|
||||
"url_privacy.save": "Save",
|
||||
"video.download": "Download file",
|
||||
"video.exit_fullscreen": "Exit full screen",
|
||||
|
||||
@ -3,10 +3,15 @@ import { create } from 'zustand';
|
||||
import { mutative } from 'zustand-mutative';
|
||||
|
||||
import { settingsSchema, type Settings } from 'pl-fe/schemas/pl-fe/settings';
|
||||
import { updateRulesFromUrl } from 'pl-fe/utils/url-purify';
|
||||
|
||||
import type { Emoji } from 'pl-fe/features/emoji';
|
||||
import type { store } from 'pl-fe/store';
|
||||
import type { APIEntity } from 'pl-fe/types/entities';
|
||||
|
||||
let lazyStore: typeof store;
|
||||
import('pl-fe/store').then(({ store }) => lazyStore = store).catch(() => {});
|
||||
|
||||
const settingsSchemaPartial = v.partial(settingsSchema);
|
||||
|
||||
type State = {
|
||||
@ -33,7 +38,16 @@ const changeSetting = (object: APIEntity, path: string[], value: any) => {
|
||||
return changeSetting(object[path[0]], path.slice(1), value);
|
||||
};
|
||||
|
||||
const mergeSettings = (state: State) => state.settings = { ...state.defaultSettings, ...state.userSettings };
|
||||
const mergeSettings = (state: State) => {
|
||||
const mergedSettings = { ...state.defaultSettings, ...state.userSettings };
|
||||
if (mergedSettings.urlPrivacy.rulesUrl && state.settings.urlPrivacy.rulesUrl !== mergedSettings.urlPrivacy.rulesUrl) {
|
||||
const me = lazyStore?.getState().me;
|
||||
if (me) {
|
||||
updateRulesFromUrl(me, mergedSettings.urlPrivacy.rulesUrl, mergedSettings.urlPrivacy.hashUrl);
|
||||
}
|
||||
}
|
||||
state.settings = mergedSettings;
|
||||
};
|
||||
|
||||
const useSettingsStore = create<State>()(mutative((set) => ({
|
||||
defaultSettings: v.parse(settingsSchema, {}),
|
||||
@ -90,4 +104,3 @@ const useSettingsStore = create<State>()(mutative((set) => ({
|
||||
}), { enableAutoFreeze: true }));
|
||||
|
||||
export { useSettingsStore };
|
||||
|
||||
|
||||
@ -15,6 +15,22 @@
|
||||
import { URLPurify, type SerializedRules } from '@mkljczk/url-purify';
|
||||
|
||||
import KVStore from 'pl-fe/storage/kv-store';
|
||||
import { Me } from 'pl-fe/types/pl-fe';
|
||||
|
||||
interface KVStoreItem {
|
||||
hashUrl: string;
|
||||
rulesUrl: string;
|
||||
hash: string;
|
||||
rules: SerializedRules;
|
||||
fetchedAt: number;
|
||||
}
|
||||
|
||||
const sha256 = async (message: string) =>
|
||||
Array.from(new Uint8Array(
|
||||
await window.crypto.subtle.digest('SHA-256', (new TextEncoder()).encode(message)),
|
||||
))
|
||||
.map((b) => b.toString(16).padStart(2, '0'))
|
||||
.join('');
|
||||
|
||||
// Adapted from ClearURLs Rules
|
||||
// https://github.com/ClearURLs/Rules/blob/master/data.min.json
|
||||
@ -90,24 +106,48 @@ const DEFAULT_RULESET: SerializedRules = {
|
||||
|
||||
const Purify = new URLPurify({
|
||||
rulesFromMemory: DEFAULT_RULESET,
|
||||
// onFetchedRules: (hash, rules) => {
|
||||
// const me = store.getState().auth.me;
|
||||
|
||||
// KVStore.setItem('url-purify-rules:last', me || '');
|
||||
// KVStore.setItem(`url-purify-rules:${me}`, {
|
||||
// hash,
|
||||
// rules,
|
||||
// fetchedAt: Date.now(),
|
||||
// });
|
||||
// },
|
||||
});
|
||||
|
||||
KVStore.getItem('url-purify-rules:last', (url: string) => {
|
||||
if (!url) return;
|
||||
KVStore.getItem(`url-purify-rules:${url}`, (rules: any) => {
|
||||
const updateRulesFromUrl = async (user: Me, rulesUrl: string, hashUrl: string, oldHash?: string) => {
|
||||
if (oldHash) {
|
||||
const newHash = await fetch(hashUrl).then((response) => response.text());
|
||||
if (newHash === oldHash) return;
|
||||
}
|
||||
|
||||
const rules = await fetch(rulesUrl).then((response) => response.text());
|
||||
|
||||
const parsedRules = JSON.parse(rules);
|
||||
const hash = await sha256(rules);
|
||||
Purify.setRules(parsedRules, hash);
|
||||
|
||||
await KVStore.setItem('url-purify-rules:last', user);
|
||||
return KVStore.setItem<KVStoreItem>(`url-purify-rules:${user}`, {
|
||||
hashUrl,
|
||||
rulesUrl,
|
||||
hash,
|
||||
rules: parsedRules,
|
||||
fetchedAt: Date.now(),
|
||||
});
|
||||
};
|
||||
|
||||
const getRulesForUser = (user: Me) => {
|
||||
if (!user || typeof user !== 'string') return;
|
||||
KVStore.getItem<KVStoreItem>(`url-purify-rules:${user}`, (rules) => {
|
||||
if (!rules) return;
|
||||
Purify.setRules(rules.rules, rules.hash);
|
||||
});
|
||||
});
|
||||
|
||||
export default Purify;
|
||||
if (rules.fetchedAt + 1000 * 60 * 60 * 24 < Date.now()) {
|
||||
updateRulesFromUrl(user, rules.rulesUrl, rules.hashUrl, rules.hash);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getRulesFromMemory = () => {
|
||||
KVStore.getItem('url-purify-rules:last', (url: string) => {
|
||||
getRulesForUser(url);
|
||||
});
|
||||
};
|
||||
|
||||
getRulesFromMemory();
|
||||
|
||||
export { Purify as default, getRulesForUser, updateRulesFromUrl };
|
||||
|
||||
Reference in New Issue
Block a user