From 9a13a1da0c275731c8975e986b6bd9a9c7c264fb Mon Sep 17 00:00:00 2001 From: CookingWithCale Date: Sun, 31 Dec 2023 23:59:35 -0800 Subject: [PATCH] Model: Update #96.A --- Extension/Ctlr/Background.ts | 22 +- Extension/Model/index.ts | 551 +++++++++++------- Extension/View/Options.tsx | 10 +- Extension/View/Popup.tsx | 14 +- .../{OptionsEditor.tsx => SettingsEditor.tsx} | 20 +- 5 files changed, 368 insertions(+), 249 deletions(-) rename Extension/View/{OptionsEditor.tsx => SettingsEditor.tsx} (78%) diff --git a/Extension/Ctlr/Background.ts b/Extension/Ctlr/Background.ts index a275a2f..5984d11 100644 --- a/Extension/Ctlr/Background.ts +++ b/Extension/Ctlr/Background.ts @@ -1,12 +1,6 @@ // Copyright AStartup; license at https://github.com/AStarStartup/AStartupMCC -import { ModelCommandStructureDefault, ModelCommandStructureSet, - ModelSessionDefault, ModelSessionSet, - ModelIssuesClosedSet, - ModelIssuesOpenSet, - ModelMissionDefault, ModelMissionSet, - ModelOptionsDefault, ModelOptionsSet, - ModelReposSet, } +import { } from '../Model' console.log("[Background.ts]") @@ -27,13 +21,15 @@ chrome.alarms.onAlarm.addListener((alarm) => { // @todo Inspect video timestamp 3:38:30 for spooky shit. +import { ModelConfigInit, ModelConfigSet, CommandStructureInit, CommandStructureSet, ModelIssueInit, ModelIssueSet, ModelMissionInit, ModelMissionSet, ModelSessionInit, ModelSessionSet, + ModelSyndicateSet } from '../Model' chrome.runtime.onInstalled.addListener(() => { - ModelOptionsSet(ModelOptionsDefault) - ModelCommandStructureSet(ModelCommandStructureDefault) - ModelIssuesClosedSet({}) - ModelIssuesOpenSet({}) - ModelMissionSet(ModelMissionDefault) - ModelReposSet({}) + ModelConfigSet(ModelConfigInit) + CommandStructureSet(CommandStructureInit) + ModelIssueSet(ModelIssueInit) + ModelMissionSet(ModelMissionInit) + ModelSessionSet(ModelSessionInit) + ModelSyndicateSet(ModelMissionInit) chrome.alarms.create("FeedUpdate", { periodInMinutes: 15/60, diff --git a/Extension/Model/index.ts b/Extension/Model/index.ts index 95e3e93..b02690c 100644 --- a/Extension/Model/index.ts +++ b/Extension/Model/index.ts @@ -1,137 +1,80 @@ // Copyright AStartup; license at https://github.com/AStarStartup/AStartupMCC -export const UsernameDefault = 'CookingWithCale' +export const UsernameInit = 'CookingWithCale' -/* Data model options that do not get synced with the server. */ -export interface ModelAppState { +export type GitHubIssue = { + title: string + number: number + brief: string } -/* Options that when changed triggers the DOM to rerender? */ -export interface ModelOptions { +export type GitHubRepo = { + name: string + issues_closed: GitHubIssue + issues_open: GitHubIssue +} + +export type GitHubAccount = { + type: string + repos: GitHubRepo +} + +/* Data model config that do not get synced with the server. */ +export type ModelAppState = { +} + +// Options that when changed triggers the DOM to rerender? +// The design goal of this data structure is to not have any nested objects. +// The ModelState data is stored using Objects and thus the key is not stored +// in the sub-Object, so we store the key of the current Object we are working +// on. +export type ModelConfig = { // App State modal_visible: boolean //< Modal is visible flag. modal_state: number //< State of the modal. content_scripts: boolean //< Content scripts enabled. // Options metric_units?: boolean //< Standard (true) or Imperial units. - username?: string //< Username. + me?: string //< The user's Username. + them?: string //< Currently selected syndicate member. session?: number //< Current session number. account?: string //< Current account. repo?: string //< Current repo. mission: number //< Current mission number. child_mission?: string //< Current child mission. - crew?: string //< Default string of crew members. -} - -// Unpacks the account/repo#MissionNumber.ChildMission from the input string. -export function MissionStringUnpack(input: string) { - let state = 0 - let account = '' - let repo = '' - let mission_number = '' - let child_mission = '' - let i = 0 - let c: string | undefined = input[i++] - let o = '\nParsing input:"' + input + '"' - while (c != undefined) { - switch(state) { - case 0: { // Parsing org - o += '\naccount:"' + account + '" c:' + c + ' i:' + i; - if(c == '/') { - c = input[i++] - state = 1 - break - } - account += c - c = input[i++] - break - } - case 1: { // Parsing repo - o += '\nrepo:"' + repo + '" c:' + c + ' i:' + i; - if(c == '#') { - c = input[i++] - state = 2 - break - } - repo += c - c = input[i++] - break - } - case 2: { // Parsing mission number. - o += '\nmission_number:"' + mission_number + '" c:' + c + ' i:' - + i; - if(c == '.') { - c = input[i++] - state = 3 - break - } - if(c < '0' || c > '9') { - console.assert(c > '', 'ERROR: invalid child mission at i:' - + i + ' c:' + c.charCodeAt(0) + ' i:' + i) - c = undefined - break - } - mission_number += c - c = input[i++] - break - } - case 3: { // Parsing Child Mission - o += '\nchild_mission:"' + child_mission + '" c:' + c + ' i:' + i; - if(c <= ' ') { - console.assert(c > '', 'ERROR: invalid child mission at i:' - + i + ' c:' + c.charCodeAt(0)) - c = undefined - break - } - child_mission += c - c = input[i++] - break - } - default: { - c = undefined - break - } - } - } - o += '\nFound account:"' + account + '" repo:"' + repo - + '" mission_number:"' + mission_number - + '" child_mission:"' + child_mission + '"' - console.log(o) - return [ account, repo, parseInt(mission_number), child_mission ] } const SessionFocusLengthMax = 100 //< Max length of a session focus heading. -export interface Model { - options?: ModelOptions //< Model data options. +// The Global App Model state. +export type ModelState = { + config?: ModelConfig //< Model data config. command_structure?: Object //< Meta model for the incident command structure. + issue?: Object //< The current issue. + mission?: Object //< The current mission. session?: Object //< Current session. - issues_open?: Object //< Missions that have not happened. - issues_closed?: Object //< Missions that have happened in the past. - mission?: Object //< Current mission. - repos?: Object //< List of this user's repos. - repo?: Object //< Current project. + syndicate?: Object //< All of the GitHubAccounts in the syndicate. } -export interface AMission { +export type AMission = { push_count: number //< Number of times this project has bee pushed. } -export interface AProject { +export type AProject = { push_count: number //< Number of times this project has bee pushed. } -export interface ACrew { - handle: string //< This crew member's unique handle. +export type ACrew = { + handle: string //< This syndicate member's unique handle. } -export interface ACommandRole { +export type ACommandRole = { master: string, //< Role master's handle. contact: Object, //< Contact information for this role. supervisor_roles: string[], //< List of supervisor roles. } -export interface ACommandStructure { +export type ACommandStructure = { rules: ACommandRole[] //< List of the roles in the ICS. } @@ -140,13 +83,13 @@ export interface ACommandStructure { export const ARoles = {} -export interface ASession { +export type ASession = { projects: Object //< Projects worked on in this session. issues: Object //< Missions log: Object //< Log for this session/... } -export interface ContentFeed { +export type ContentFeed = { title: string //< Title of the feed. description: string //< Description of the feed. handle: string //< Handle of the feed. @@ -155,7 +98,7 @@ export interface ContentFeed { header: string //< HTML/CSS header for this feed. } -export interface ContentFeedCategory { +export type ContentFeedCategory = { title: string //< Title of the category. color: string //< Identifying color. icon: string //< Icon for the category. @@ -163,13 +106,13 @@ export interface ContentFeedCategory { feeds: ContentFeed[] //< Array of feeds in this category. } -export interface Enclosure { +export type Enclosure = { url: string length: number type: string } -export interface ContentFeedItem { +export type ContentFeedItem = { uid: bigint //< 128-bit Unique ID. idx: bigint //< 64-bit inode index. link: string //< Link to the feed item target. @@ -185,36 +128,113 @@ export interface ContentFeedItem { word_bag: Object //< Object containing the bag of words values. } -export interface AForm { +export type AForm = { title: string, //< Form title. description: string, //< Form description. instructions: string, //< Instructions on completing the form. log: Object //< Form change log. } -export interface ACommandStructure { +export type ACommandStructureNode = { master: string, //< Master of this role (i.e the boss) contact: Object, //< Contact information for this role. supervisor: string, //< Supervisor role key of this role. } -export type ModelKeys = keyof Model +export type ModelKeys = keyof ModelState -export const ModelOptionsDefault: ModelOptions = { +export const ModelConfigInit: ModelConfig = { modal_visible: false, modal_state: 0, content_scripts: false, metric_units: true, - username: UsernameDefault, + me: UsernameInit, + them: '', session: 0, account: '', repo: '', mission: 0, - child_mission: '', - crew: UsernameDefault, + child_mission: '' +} +// Unpacks the account/repo#MissionNumber.ChildMission from the input string. +export function MissionStringUnpack(input: string) { + let state = 0 + let account = '' + let repo = '' + let mission_number = '' + let child_mission = '' + let i = 0 + let c: string | undefined = input[i++] + let o = '\nParsing input:"' + input + '"' + while (c != undefined) { + switch(state) { + case 0: { // Parsing org + o += '\naccount:"' + account + '" c:' + c + ' i:' + i; + if(c == '/') { + c = input[i++] + state = 1 + break + } + account += c + c = input[i++] + break + } + case 1: { // Parsing repo + o += '\nrepo:"' + repo + '" c:' + c + ' i:' + i; + if(c == '#') { + c = input[i++] + state = 2 + break + } + repo += c + c = input[i++] + break + } + case 2: { // Parsing mission number. + o += '\nmission_number:"' + mission_number + '" c:' + c + ' i:' + + i; + if(c == '.') { + c = input[i++] + state = 3 + break + } + if(c < '0' || c > '9') { + console.assert(c > '', 'ERROR: invalid child mission at i:' + + i + ' c:' + c.charCodeAt(0) + ' i:' + i) + c = undefined + break + } + mission_number += c + c = input[i++] + break + } + case 3: { // Parsing Child Mission + o += '\nchild_mission:"' + child_mission + '" c:' + c + ' i:' + i; + if(c <= ' ') { + console.assert(c > '', 'ERROR: invalid child mission at i:' + + i + ' c:' + c.charCodeAt(0)) + c = undefined + break + } + child_mission += c + c = input[i++] + break + } + default: { + c = undefined + break + } + } + } + o += '\nFound account:"' + account + '" repo:"' + repo + + '" mission_number:"' + mission_number + + '" child_mission:"' + child_mission + '"' + console.log(o) + return [ account, repo, parseInt(mission_number), child_mission ] } -export const ModelCommandStructureDefault = { +// The vanilla Incident Command System Structure. +export const CommandStructureInit = { 'command_roles': { ['Commander']: { 'master': null, @@ -259,41 +279,185 @@ export const ModelCommandStructureDefault = { } } -export const ModelDefault: Model = { - options: ModelOptionsDefault, - command_structure: ModelCommandStructureDefault, - session: {}, - issues_open: {}, - issues_closed: {}, +export const ModelStateInit: ModelState = { + command_structure: CommandStructureInit, + issue: {}, mission: {}, - repos: {}, - repo: {}, -} - -export const ModelSessionsFutureDefault = {} -export const ModelSessionsPastDefault = {} -export const ModelSessionDefault = {} -export const ModelMissionsFutureDefault = {} -export const ModelMissionsPastDefault = {} -export const ModelMissionDefault = {} -export const ModelProjectsColdDefault = {} -export const ModelProjectsWarmDefault = {} -export const ModelProjectsHotDefault = {} -export const ModelProjectsDoneDefault = {} -export const ModelProjectDefault = {} - -export function ModelOptionsGet(): Promise { - const keys: ModelKeys[] = ['options'] + config: ModelConfigInit, + session: {}, + syndicate: { + "CookingWithCale": { + "Repos": { + "AStarStartup/AStartupMCC": { + "Visibility": true + }, + "AStarStartup/AStartupToolkit": { + "Visibility": true + }, + "AStarStartup/LinearId": { + "Visibility": true + }, + "AStarStartup/OBSFX": { + "Visibility": true + }, + "AStarStartup/.github": { + "Visibility": true + }, + "AStarStartup/AStartupGitTemplate": { + "Visibility": true + }, + "AStarStartup/AStartupCookbook": { + "Visibility": true + }, + "AStarStartup/AStartupWorld": { + "Visibility": false + }, + "AStarStartup/StreamSeq": { + "Visibility": false + }, + "AStarStartup/Channel": { + "Visibility": false + }, + "AStarStartup/OBSTouchGIMP": { + "Visibility": false + }, + "AStarStartup/Typecraft": { + "Visibility": false + }, + "KabukiStarship/Script2": { + "Visibility": true + }, + "KabukiStarship/.github": { + "Visibility": true + }, + "KabukiStarship/Actors": { + "Visibility": true + }, + "KabukiStarship/iGeekPolygonWorld": { + "Visibility": true + }, + "KabukiStarship/KabukiLIcenses": { + "Visibility": true + }, + "KabukiStarship/iGeekCookbook": { + "Visibility": true + }, + "KabukiStarship/StarshipCookbook": { + "Visibility": true + }, + "KabukiStarship/KabukiPressCookbook": { + "Visibility": true + }, + "KabukiStarship/MusictechCookbook": { + "Visibility": true + }, + "KabukiStarship/iGeek": { + "Visibility": true + }, + "KabukiStarship/iGeekCardsWorld": { + "Visibility": true + }, + "KabukiStarship/KabukiStarship.github.io": { + "Visibility": true + }, + "KabukiStarship/KabukiToolkit": { + "Visibility": true + }, + "KabukiStarship/IMUL": { + "Visibility": true + }, + "KabukiStarship/ScriptTek": { + "Visibility": true + }, + "KabukiStarship/iGeekMazeWorld": { + "Visibility": true + }, + "KabukiStarship/iGeekPacWorld": { + "Visibility": true + }, + "KabukiStarship/iGeekTileWorld": { + "Visibility": true + }, + "KabukiStarship/iGeekVirusWorld": { + "Visibility": true + }, + "KabukiStarship/KabukiBenchmark": { + "Visibility": true + }, + "KabukiStarship/KabukiPress": { + "Visibility": false + }, + "KabukiStarship/KabukiSearch": { + "Visibility": false + }, + "KabukiStarship/SearchFor4.669": { + "Visibility": false + }, + "KabukiStarship/IAmPy": { + "Visibility": false + }, + "KabukiStarship/iGeekWikiWorld": { + "Visibility": false + }, + "KabukiStarship/iGeekUlator": { + "Visibility": false + }, + "KabukiStarship/iGeekBlockWorld": { + "Visibility": false + }, + "KabukiStarship/KabukiDB": { + "Visibility": false + }, + "KabukiStarship/KabukiTheater": { + "Visibility": false + }, + "CookingWithCale/BadThing": { + "Visibility": true + }, + "CookingWithCale/.github": { + "Visibility": true + }, + "CookingWithCale/FreedomCookbook": { + "Visibility": true + }, + "CookingWithCale/MarkdownCookbook": { + "Visibility": true + }, + "CookingWithCale/MarkdownSoftwareEngineering": { + "Visibility": true + }, + "CookingWithCale/SickBay>": { + "Visibility": true + }, + "CookingWithCale/MarkdownGameDev": { + "Visibility": true + }, + "CookingWithCale/metascrapper": { + "Visibility": false + }, + "CookingWithCale/MetamediaDownloader": { + "Visibility": false + }, + "CookingWithCale/Self": { + "Visibility": false + } + } + }, + } +} + +export function ModelConfigGet(): Promise { + const keys: ModelKeys[] = ['config'] return new Promise((resolve) => { - chrome.storage.local.get(keys, (res: Model) => { - resolve(res.options ?? ModelOptionsDefault) + chrome.storage.local.get(keys, (state: ModelState) => { + resolve(state.config ?? ModelConfigInit) }) }) } -export function ModelOptionsSet(options: ModelOptions): Promise { - const Values: Model = { - options, +export function ModelConfigSet(config: ModelConfig): Promise { + const Values: ModelState = { + config: config, } return new Promise((resolve) => { chrome.storage.local.set(Values, () => { @@ -302,17 +466,17 @@ export function ModelOptionsSet(options: ModelOptions): Promise { }) } -export function ModelCommandStructureGet(): Promise { +export function CommandStructureGet(): Promise { const keys: ModelKeys[] = ['command_structure'] return new Promise((resolve) => { - chrome.storage.local.get(keys, (res: Model) => { - resolve(res.options ?? ModelOptionsDefault) + chrome.storage.local.get(keys, (state: ModelState) => { + resolve(state.config ?? ModelStateInit) }) }) } -export function ModelCommandStructureSet(command_structure: Object): Promise { - const Values: Model = { +export function CommandStructureSet(command_structure: Object): Promise { + const Values: ModelState = { command_structure, } return new Promise((resolve) => { @@ -322,18 +486,18 @@ export function ModelCommandStructureSet(command_structure: Object): Promise { - const keys: ModelKeys[] = ['session'] +export function ModelIssueGet(): Promise { + const keys: ModelKeys[] = ['issue'] return new Promise((resolve) => { - chrome.storage.local.get(keys, (res: Model) => { - resolve(res.options ?? ModelOptionsDefault) + chrome.storage.local.get(keys, (state: ModelState) => { + resolve(state.issue ?? {}) }) }) } -export function ModelSessionSet(session: Object): Promise { - const Values: Model = { - session, +export function ModelIssueSet(issue: Object): Promise { + const Values: ModelState = { + issue, } return new Promise((resolve) => { chrome.storage.local.set(Values, () => { @@ -342,38 +506,24 @@ export function ModelSessionSet(session: Object): Promise { }) } -export function ModelMissionsPastStructureGet(): Promise { - const keys: ModelKeys[] = ['issues_closed'] +export function ModelMissionGet(): Promise { + const keys: ModelKeys[] = ['mission'] return new Promise((resolve) => { - chrome.storage.local.get(keys, (res: Model) => { - resolve(res.options ?? ModelOptionsDefault) + chrome.storage.local.get(keys, (state: ModelState) => { + resolve(state.mission ?? {}) }) }) } -export function ModelMissionsPastSet(issues_closed: Object): Promise { - const Values: Model = { - issues_closed: issues_closed, - } - return new Promise((resolve) => { - chrome.storage.local.set(Values, () => { - resolve() - }) - }) -} +export const ModelIssueInit = {} -export function ModelIssuesOpenGet(): Promise { - const keys: ModelKeys[] = ['issues_open'] - return new Promise((resolve) => { - chrome.storage.local.get(keys, (res: Model) => { - resolve(res.options ?? ModelOptionsDefault) - }) - }) -} +export const ModelMissionInit = {} + +export const ModelSessionInit = {} -export function ModelIssuesOpenSet(issues_open: Object): Promise { - const Values: Model = { - issues_open: issues_open, +export function ModelMissionSet(mission: Object): Promise { + const Values: ModelState = { + mission, } return new Promise((resolve) => { chrome.storage.local.set(Values, () => { @@ -382,18 +532,9 @@ export function ModelIssuesOpenSet(issues_open: Object): Promise { }) } -export function ModelIssuesClosedGet(): Promise { - const keys: ModelKeys[] = ['issues_closed'] - return new Promise((resolve) => { - chrome.storage.local.get(keys, (res: Model) => { - resolve(res.options ?? ModelOptionsDefault) - }) - }) -} - -export function ModelIssuesClosedSet(issues: Object): Promise { - const Values: Model = { - issues_closed: issues, +export function ModelSessionSet(session: Object): Promise { + const Values: ModelState = { + session, } return new Promise((resolve) => { chrome.storage.local.set(Values, () => { @@ -402,38 +543,22 @@ export function ModelIssuesClosedSet(issues: Object): Promise { }) } -export function ModelMissionGet(): Promise { - const keys: ModelKeys[] = ['mission'] - return new Promise((resolve) => { - chrome.storage.local.get(keys, (res: Model) => { - resolve(res.options ?? ModelOptionsDefault) - }) - }) -} - -export function ModelMissionSet(mission: Object): Promise { - const Values: Model = { - mission, - } - return new Promise((resolve) => { - chrome.storage.local.set(Values, () => { - resolve() - }) - }) +export const ModelSyndicateInit: Object = { + "CookingWithCale": {} } -export function ModelReposGet(): Promise { - const keys: ModelKeys[] = ['repos'] +export function ModelSyndicateGet(): Promise { + const keys: ModelKeys[] = ['syndicate'] return new Promise((resolve) => { - chrome.storage.local.get(keys, (res: Model) => { - resolve(res.options ?? ModelOptionsDefault) + chrome.storage.local.get(keys, (state: ModelState) => { + resolve(state.syndicate ?? ModelSyndicateInit) }) }) } -export function ModelReposSet(repos: Object): Promise { - const Values: Model = { - repos, +export function ModelSyndicateSet(syndicate: Object): Promise { + const Values: ModelState = { + syndicate, } return new Promise((resolve) => { chrome.storage.local.set(Values, () => { diff --git a/Extension/View/Options.tsx b/Extension/View/Options.tsx index aef449c..bd1fadb 100644 --- a/Extension/View/Options.tsx +++ b/Extension/View/Options.tsx @@ -4,8 +4,8 @@ import React, { useEffect, useReducer, useState } from 'react' import { createRoot } from 'react-dom/client' import { - ModelCommandStructureDefault, ModelOptions, - ModelOptionsDefault, ModelOptionsGet + CommandStructureInit, ModelConfig, + ModelConfigInit, ModelConfigGet } from '../Model' const OptionsView = () => { @@ -23,13 +23,13 @@ const OptionsView = () => { } const [CommandStructure, CommandStructureSet] = - useState(ModelCommandStructureDefault) + useState(CommandStructureInit) const [Visible, VisibleSet] = useState(false) const [State, StateSet] = useState(0) const [IsSaving, IsSavingSet] = useState(false) const [Mode, ModeSet] = useState(Modes.Options) const [Options, OptionsSet] = - useState(ModelOptionsDefault) + useState(ModelConfigInit) const SaveButtonStyles = 'block mt-10 border-none outline-none' + 'rounded-md p-4 bg-violet-500 font-bold' @@ -37,7 +37,7 @@ const OptionsView = () => { useEffect(() => { console.log('[useEffect]') - ModelOptionsGet().then(options_new => OptionsSet(options_new)) + ModelConfigGet().then(options_new => OptionsSet(options_new)) }, []) const ReduceState = (state, action) => { diff --git a/Extension/View/Popup.tsx b/Extension/View/Popup.tsx index f768075..15215a2 100644 --- a/Extension/View/Popup.tsx +++ b/Extension/View/Popup.tsx @@ -2,19 +2,19 @@ import React, { useEffect, useState, useReducer } from 'react'; import { createRoot } from 'react-dom/client'; -import { ModelOptions, ModelOptionsDefault, ModelOptionsGet } from '../Model'; +import { ModelConfig, ModelConfigInit, ModelConfigGet } from '../Model'; const Popup = () => { console.log('>Popup'); - const [Options, OptionsSet] = useState( - ModelOptionsDefault); + const [Config, ConfigSet] = useState( + ModelConfigInit); const [IsSaving, IsSavingSet] = useState(false); - if (Options == null) return
Options == null
- let { username, session, account, repo, mission, child_mission } = Options; + if (Config == null) return
Options == null
+ let { me: username, session, account, repo, mission, child_mission } = Config; useEffect(() => { console.log('[useEffect]'); - ModelOptionsGet().then(options_new => OptionsSet(options_new)); + ModelConfigGet().then(options_new => ConfigSet(options_new)); }, []); const SessionFocusChange = (username: string) => { @@ -37,7 +37,7 @@ const Popup = () => {
{child_mission}
SessionFocusChange(event.target.value) } disabled={ IsSaving } /> diff --git a/Extension/View/OptionsEditor.tsx b/Extension/View/SettingsEditor.tsx similarity index 78% rename from Extension/View/OptionsEditor.tsx rename to Extension/View/SettingsEditor.tsx index 809cba7..31cce15 100644 --- a/Extension/View/OptionsEditor.tsx +++ b/Extension/View/SettingsEditor.tsx @@ -1,27 +1,25 @@ // Copyright AStartup; license at https://github.com/AStarStartup/AStartupMCC -import { ModelAppState, ModelOptions } from '../Model' +import { ModelAppState, ModelConfig } from '../Model' import React, { Dispatch, useState } from "react"; -const OptionsEditor = (props: { - options: ModelOptions, +const ConfigEditor = (props: { + options: ModelConfig, dispatch: Dispatch, is_saving: boolean, }) => { let { options, dispatch, is_saving } = props; if (options == undefined || dispatch == undefined) return null; - let { content_scripts, crew, username, metric_units } = options; + let { content_scripts, me, metric_units } = options; if (content_scripts == undefined || metric_units == undefined || - crew == undefined || username == undefined) return null + me == undefined) return null const [ContentScripts, ContentScriptsSet] = useState(content_scripts == true ? 'Enabled' : 'Disabled') const [MetricUnits, MetricUnitsSet] = useState(metric_units == true ? 'Standard' : 'Imperial') - const [Crew, CrewSet] = useState(crew) - const [Username, UsernameSet] = useState(username) - const UsernameChange = (username: string) => { + const UsernameChange = (me: string) => { } const ContentScriptsChange = ( @@ -41,8 +39,8 @@ const OptionsEditor = (props: { return

Options

Username - UsernameChange(event.target.value)} disabled={ is_saving } @@ -69,4 +67,4 @@ const OptionsEditor = (props: {
} -export default OptionsEditor +export default ConfigEditor