import {Component, render} from "preact"; import browser from "webextension-polyfill"; import {type Value} from "@holllo/webextension-storage"; import "../scss/index.scss"; import { Link, createReportTemplate, initializeGlobals, } from "../utilities/exports.js"; import {type Feature, Data, fromStorage} from "../storage/exports.js"; import {AppContext} from "./context.js"; import {features} from "./features.js"; window.addEventListener("DOMContentLoaded", async () => { if ($test) { await import("../storage/migrations/migrations.test.js"); } initializeGlobals(); const manifest = browser.runtime.getManifest(); render(, document.body); }); type Props = { manifest: browser.Manifest.WebExtensionManifest; }; type State = { activeFeature: Value; enabledFeatures: Value>; }; class App extends Component { state: State; // Duration for how long the "NEW" indicator should appear next to a feature, // currently 14 days. readonly newFeatureDuration = 14 * 24 * 60 * 60 * 1000; constructor(props: Props) { super(props); this.state = { activeFeature: undefined!, enabledFeatures: undefined!, }; } async componentDidMount() { this.setState({ activeFeature: await fromStorage(Data.LatestActiveFeatureTab), enabledFeatures: await fromStorage(Data.EnabledFeatures), }); } setActiveFeature = (feature: Feature) => { const {activeFeature} = this.state; activeFeature.value = feature; void activeFeature.save(); this.setState({activeFeature}); }; toggleFeature = (feature: Feature) => { const {enabledFeatures} = this.state; if (enabledFeatures.value.has(feature)) { enabledFeatures.value.delete(feature); } else { enabledFeatures.value.add(feature); } void enabledFeatures.save(); this.setState({enabledFeatures}); }; render() { const {manifest} = this.props; const {activeFeature, enabledFeatures} = this.state; if (activeFeature === undefined || enabledFeatures === undefined) { return; } // Create the version link for the header. const version = manifest.version; const versionUrl = encodeURI( `https://gitlab.com/tildes-community/tildes-reextended/-/releases/${version}`, ); const versionLink = ( ); // Create the GitLab report a bug link for the footer. const gitlabTemplate = createReportTemplate("gitlab", version); const gitlabUrl = encodeURI( `https://gitlab.com/tildes-community/tildes-reextended/issues/new?issue[description]=${gitlabTemplate}`, ); const gitlabLink = ; // Create the Tildes report a bug link for the footer. const tildesReportTemplate = createReportTemplate("tildes", version); const tildesUrl = encodeURI( `https://tildes.net/user/Community/new_message?subject=Tildes ReExtended Bug&message=${tildesReportTemplate}`, ); const tildesLink = ; const asideElements = features.map( ({availableSince, lastUpdated, key, title}) => { const lastUpdatedTime = lastUpdated?.getTime() ?? this.newFeatureDuration * 2; const isNew = Date.now() - availableSince.getTime() < this.newFeatureDuration; const isUpdated = Date.now() - lastUpdatedTime < this.newFeatureDuration; const isNewOrUpdated = isNew ? ( NEW ) : isUpdated ? ( UPDATED ) : undefined; return (
  • { this.setActiveFeature(key); }} > {title} {isNewOrUpdated}
  • ); }, ); const mainElements = features.map(({key, title, component: Setting}) => { return ( ); }); return (
    {mainElements}
    ); } }