wayBetter for X 1.0.2

This commit is contained in:
CRTkafa 2026-10-02 02:54:04 +07:00
parent 660531daeb
commit 6f6721d32d
212 changed files with 10208 additions and 2345 deletions

View file

@ -26,7 +26,13 @@ import { PRODUCT, X_PALETTE } from './paletteModel';
import { isXUrl } from './paneModel';
import { HOME_URL, LOGIN_URL, LOGOUT_URL, X_ACCOUNT_RULES } from './profileModel';
import { xSearchUrl } from './searchInput';
import { themes } from './themes';
import { syncWording } from './stringPacks';
import { areaFlag, normalizeFlags, sparseFlags } from '../../../../waybetter/packages/runtime/src/featureTable.ts';
import { flagsChanged } from '../../../../waybetter/packages/shell/src/panel/PluginFeatures.tsx';
import { X_AREAS, X_TABLE } from '../areas/table';
import { X_ICON_PACKS } from '../inject/themeStructure';
import { installController } from './installStore';
import { setChoice, themeState, themes } from './themes';
import { X_DECK, searchCompleter } from './xColumns';
const X = 'https://x.com';
@ -52,6 +58,8 @@ function readWording() {
siteChanged();
})
.catch(() => {});
// The wording is also a string pack: the tabs get it (or lose it) when the setting changed.
void syncWording();
}
export const X_SITE: ShellSite = {
@ -86,15 +94,56 @@ export const X_SITE: ShellSite = {
version: getVersion,
// "Report a problem": the public repo's new-issue page, and which features paused themselves.
report: { issueUrl: 'https://git.crt.fyi/CRT/waybetter-for-x/issues/new', details: reportDetails },
// The macOS menu bar (waybetter-host menu.rs): the eight area plugins, the icon packs and the app's own File and Help items.
native: {
plugins: {
async list() {
const flags = normalizeFlags(X_TABLE, await invoke('features_get'));
return X_AREAS.map(area => ({ id: area.id, label: area.name, checked: flags[areaFlag(area.id)] !== false }));
},
async set(id, on) {
const flags = normalizeFlags(X_TABLE, await invoke('features_get'));
await invoke('features_set', { features: sparseFlags(X_TABLE, { ...flags, [areaFlag(id)]: on }) });
flagsChanged();
},
subscribe: listener => { window.addEventListener('wb-features-changed', listener); return () => window.removeEventListener('wb-features-changed', listener); },
},
iconPacks: {
list() {
const choice = themeState().choice;
const current = choice.icons ?? 'theme';
const packs = [...X_ICON_PACKS.packs, ...(choice.packs ?? []).filter(pack => !X_ICON_PACKS.packs.some(item => item.id === pack.id))];
return [
{ id: 'theme', label: t('wb.appearance.icons.theme'), checked: current === 'theme' },
{ id: 'site', label: t('wb.appearance.icons.site'), checked: current === 'site' },
...packs.map(pack => ({ id: pack.id, label: pack.name, checked: current === pack.id })),
];
},
async set(id) { const choice = themeState().choice; await setChoice({ ...choice, icons: id === 'theme' ? undefined : id }); },
subscribe: listener => themes.subscribe(listener),
},
// A file picked here goes through the same install screen as a dropped one: nothing installs without it.
installFromFile() {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.json,.js';
input.addEventListener('change', () => { const file = input.files?.[0]; if (file) void installController.requestFile(file); });
input.click();
},
shareSetup: () => shell.openPanelSection('backup'),
docs: () => shell.openPanelSection('make'),
website: { label: 'waybetter.fyi', url: 'https://waybetter.fyi' },
},
},
overlays: [DraftPickerHost, InstallHost],
start() {
// The tweak is set in the wayBetter panel; coming back to the window picks up a change.
readWording();
window.addEventListener('focus', readWording);
window.addEventListener('wb-features-changed', readWording);
// The first-run screen (Basic / Advanced / Power User) is the panel's: open it when it is due.
openOnboardingWhenDue();
return () => window.removeEventListener('focus', readWording);
return () => { window.removeEventListener('focus', readWording); window.removeEventListener('wb-features-changed', readWording); };
},
};