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()}
+ />
+ ) : (
+
+ )}
+
+ )
+})
+
+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 }) => {
)}
>
-
+
{!hide && (
<>
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 })
+ }
}