diff --git a/packages/extension/src/js/components/Window/Title.tsx b/packages/extension/src/js/components/Window/Title.tsx index 1fbdf5f49..8ef4c9929 100644 --- a/packages/extension/src/js/components/Window/Title.tsx +++ b/packages/extension/src/js/components/Window/Title.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useEffect } from 'react' +import React, { useRef, useEffect, useState } from 'react' import { observer } from 'mobx-react-lite' import SelectAll from 'components/Window/SelectAll' import Sort from 'components/Window/Sort' @@ -10,16 +10,67 @@ import HideToggle from './HideToggle' import { WinProps } from 'components/types' import useReduceMotion from 'libs/useReduceMotion' -export default observer((props: WinProps & { className: string }) => { - const nodeRef = useRef(null) - const { className, win } = props - const { tabs, activate, invisibleTabs, reload, hide, toggleHide, isFocused } = - win +export const Title = (props) => { + const { title, text, invisibleIndicator, hide } = props + + return ( +
+ {title ? title : text} {!hide && invisibleIndicator} +
+ ) +} +export const EditableTitle = observer((props: WinProps) => { + const { win } = props + const { tabs, invisibleTabs, hide, title, setTitle } = win const { length } = tabs const text = `${length} ${getNoun('tab', length)}` const invisibleLength = invisibleTabs.length const invisibleIndicator = invisibleLength > 0 && `/ ${invisibleLength} hidden` + + const [editing, setEditing] = useState(false) + const [value, setValue] = useState(title || text) + useEffect(() => { + setValue(title || text) + }, [title, text]) + + return ( +
{ + setEditing((x) => !x) + }} + > + {editing ? ( + { + setValue(e.target.value) + }} + onKeyDown={(e) => { + if (e.key === 'Enter') { + e.preventDefault() + setTitle(value) + setEditing(false) + } else if (e.key === 'Escape') { + e.preventDefault() + setEditing(false) + } + }} + value={value} + onFocus={(e) => e.currentTarget.select()} + /> + ) : ( + + )} + </div> + ) +}) + +export default observer((props: WinProps & { className: string }) => { + const nodeRef = useRef(null) + const { className, win } = props + const { reload, hide, toggleHide, isFocused } = win const reduceMotion = useReduceMotion() useEffect(() => { if (isFocused) { @@ -42,14 +93,7 @@ export default observer((props: WinProps & { className: string }) => { )} > <SelectAll {...props} /> - <button - onClick={activate} - className="flex-auto overflow-hidden text-base text-left rounded-sm" - > - <h5 className="flex-auto text-2xl whitespace-nowrap"> - {text} {!hide && invisibleIndicator} - </h5> - </button> + <EditableTitle {...props} /> {!hide && ( <> <Sort {...props} /> diff --git a/packages/extension/src/js/stores/Window.tsx b/packages/extension/src/js/stores/Window.tsx index 95856fffa..08d4e0ac9 100644 --- a/packages/extension/src/js/stores/Window.tsx +++ b/packages/extension/src/js/stores/Window.tsx @@ -15,6 +15,9 @@ export default class Window extends Focusable { tabs: observable, showTabs: observable, type: observable, + title: observable, + getTitle: action, + setTitle: action, activate: action, hide: computed, visibleLength: computed, @@ -42,6 +45,7 @@ export default class Window extends Focusable { this.tabs = win.tabs.map((tab) => new Tab(tab, store, this)) // TODO: Remove this when we add concurrent mode this.showTabs = !this.store.windowStore.initialLoading + this.getTitle() } tabs: Tab[] = [] @@ -51,10 +55,16 @@ export default class Window extends Focusable { type = '' + title = '' + activate = () => { browser.windows.update(this.id, { focused: true }) } + get key() { + return `win-${this.id}` + } + get hide() { return this.store.hiddenWindowStore.hiddenWindows[this.id] } @@ -216,4 +226,16 @@ export default class Window extends Focusable { this.store.focusStore.focus(this) } } + + getTitle = async () => { + const res = await browser.storage.local.get({ [this.key]: '' }) + const title = res[this.key] + console.log('key:', res, title) + this.title = title + } + + setTitle = async (title: string) => { + this.title = title + await browser.storage.local.set({ [this.key]: title }) + } }