wayBetter for X
This commit is contained in:
commit
434f193217
720 changed files with 147465 additions and 0 deletions
105
apps/desktop/src/shell/site.tsx
Normal file
105
apps/desktop/src/shell/site.tsx
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
// wayBetter for X on the wayBetter shell frame: what the frame needs to know about X (its pages,
|
||||
// accounts, address chips, search, palette items, deck columns, the compose dock, which pages have
|
||||
// a composer, the Twitter/X wording) and the app's own pieces (the wayBetter panel, the drafts
|
||||
// picker, the install screen). Importing this module sets the frame up; `Shell` is its root.
|
||||
|
||||
import { getVersion } from '@tauri-apps/api/app';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window';
|
||||
// The panel and the install screen first: their styles load before the frame's shell.css, which
|
||||
// wins where class names meet (the panel's .bt-seg control vs the address bar's .bt-seg chips).
|
||||
import { Panel } from '../ui/Panel';
|
||||
import { InstallHost } from './InstallDialog';
|
||||
import { DEFAULT_MENU, createShell, menuWith, shell, siteChanged, type ShellSite } from '../../../../waybetter/packages/shell/src/frame/index.ts';
|
||||
import type { IconName } from '../../../../waybetter/packages/shell/src/frame/icons.tsx';
|
||||
import { menuModes, openOnboardingWhenDue } from '../../../../waybetter/packages/shell/src/panel/Modes.tsx';
|
||||
import { reportDetails } from '../../../../waybetter/packages/shell/src/panel/PluginFeatures.tsx';
|
||||
import { i18n, LANGUAGES, t, tx } from '../i18n/index.ts';
|
||||
import { language } from '../i18n/language.ts';
|
||||
import { LOGO_PNG } from '../ui/logo-data';
|
||||
import { parseAddress } from './addressModel';
|
||||
import { COMPOSE_URL, COMPOSE_WIDTH, ComposeDock, composeNavigated } from './ComposeDock';
|
||||
import { DraftPickerHost } from './DraftPicker';
|
||||
import { isXUrl as hasComposer } from './mediaModel';
|
||||
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 { X_DECK, searchCompleter } from './xColumns';
|
||||
|
||||
const X = 'https://x.com';
|
||||
|
||||
/** X's own pages on the new-tab page; names are `newtab.link.<id>` in the catalogs (X's own words for them). */
|
||||
const LINKS: Array<{ id: string; icon: IconName; path: string | null }> = [
|
||||
{ id: 'home', icon: 'home', path: null },
|
||||
{ id: 'notifications', icon: 'bell', path: '/notifications' },
|
||||
{ id: 'messages', icon: 'mail', path: '/messages' },
|
||||
{ id: 'bookmarks', icon: 'bookmark', path: '/i/bookmarks' },
|
||||
{ id: 'explore', icon: 'explore', path: '/explore' },
|
||||
{ id: 'lists', icon: 'list', path: '/i/lists' },
|
||||
];
|
||||
|
||||
/** Site-chip wording in the address bar and the new-tab search: the `twitterWording` tweak. */
|
||||
let wording: 'twitter' | 'x' = 'twitter';
|
||||
function readWording() {
|
||||
invoke<{ twitterWording?: boolean }>('features_get')
|
||||
.then(features => {
|
||||
const next = features?.twitterWording === false ? 'x' : 'twitter';
|
||||
if (next === wording) return;
|
||||
wording = next;
|
||||
siteChanged();
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
export const X_SITE: ShellSite = {
|
||||
name: 'X',
|
||||
product: PRODUCT,
|
||||
deferWindowShow: true,
|
||||
logo: LOGO_PNG,
|
||||
homeUrl: HOME_URL,
|
||||
loginUrl: LOGIN_URL,
|
||||
logoutUrl: LOGOUT_URL,
|
||||
isSiteUrl: isXUrl,
|
||||
accounts: X_ACCOUNT_RULES,
|
||||
searchUrl: xSearchUrl,
|
||||
address: url => parseAddress(url, wording),
|
||||
addressCompleter: searchCompleter(),
|
||||
panel: { id: 'better-twttr', title: 'wayBetter', component: Panel },
|
||||
newTab: {
|
||||
search: () => t('newtab.search', { site: wording === 'x' ? 'X' : 'Twitter' }),
|
||||
links: LINKS.map(link => ({ id: link.id, icon: link.icon, label: () => tx(`newtab.link.${link.id}`), url: home => (link.path ? X + link.path : home) })),
|
||||
},
|
||||
palette: X_PALETTE,
|
||||
deck: { ...X_DECK, compose: { url: COMPOSE_URL, width: COMPOSE_WIDTH, Dock: ComposeDock, navigated: composeNavigated } },
|
||||
media: { canAttach: hasComposer },
|
||||
// The panel's Languages section (string packs) is there: the app menu links to it.
|
||||
features: { strings: true },
|
||||
themes,
|
||||
// The app menu (the titlebar's "Settings and more", Alt+F): the framework's rows, and the draft vault beside the panel's other sections.
|
||||
menu: {
|
||||
groups: menuWith(DEFAULT_MENU, 'workspaces', [{ id: 'drafts', icon: 'draft', label: () => `${tx('palette.section.drafts')}…`, run: () => shell.openPanelSection('drafts') }]),
|
||||
languages: { list: LANGUAGES, state: language.state, subscribe: language.subscribe, set: language.set },
|
||||
modes: menuModes(),
|
||||
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 },
|
||||
},
|
||||
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);
|
||||
// The first-run screen (Basic / Advanced / Power User) is the panel's: open it when it is due.
|
||||
openOnboardingWhenDue();
|
||||
return () => window.removeEventListener('focus', readWording);
|
||||
},
|
||||
};
|
||||
|
||||
export const Shell = createShell(X_SITE, {
|
||||
native: { invoke, listen, currentWindow: getCurrentWindow },
|
||||
i18n,
|
||||
dev: import.meta.env.DEV,
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue