mirror of
https://github.com/vale981/tridactyl
synced 2025-03-06 01:51:40 -05:00
Impletment sessions completion
Sessions completion let us provide completions for the `:undo` ex command, which can be useful if you need to restore an older tab. Closes https://github.com/tridactyl/tridactyl/issues/1127.
This commit is contained in:
parent
e62eae4d15
commit
a353c51354
4 changed files with 106 additions and 1 deletions
|
@ -30,6 +30,7 @@ import { HelpCompletionSource } from "@src/completions/Help"
|
|||
import { HistoryCompletionSource } from "@src/completions/History"
|
||||
import { PreferenceCompletionSource } from "@src/completions/Preferences"
|
||||
import { RssCompletionSource } from "@src/completions/Rss"
|
||||
import { SessionsCompletionSource } from "@src/completions/Sessions"
|
||||
import { SettingsCompletionSource } from "@src/completions/Settings"
|
||||
import * as Messaging from "@src/lib/messaging"
|
||||
import * as Config from "@src/lib/config"
|
||||
|
@ -101,8 +102,9 @@ export function enableCompletions() {
|
|||
HelpCompletionSource,
|
||||
HistoryCompletionSource,
|
||||
PreferenceCompletionSource,
|
||||
SettingsCompletionSource,
|
||||
RssCompletionSource,
|
||||
SessionsCompletionSource,
|
||||
SettingsCompletionSource,
|
||||
]
|
||||
.map(constructorr => {
|
||||
try {
|
||||
|
|
85
src/completions/Sessions.ts
Normal file
85
src/completions/Sessions.ts
Normal file
|
@ -0,0 +1,85 @@
|
|||
import { browserBg } from "@src/lib/webext.ts"
|
||||
import * as Completions from "@src/completions"
|
||||
|
||||
function computeDate(session) {
|
||||
let howLong = Math.round(
|
||||
((new Date() as any) - session.lastModified) / 1000,
|
||||
)
|
||||
let qualifier = "s"
|
||||
if (howLong > 60) {
|
||||
qualifier = "m"
|
||||
howLong = Math.round(howLong / 60)
|
||||
if (howLong > 60) {
|
||||
qualifier = "h"
|
||||
howLong = Math.round(howLong / 60)
|
||||
if (howLong > 24) {
|
||||
qualifier = "d"
|
||||
howLong = Math.round(howLong / 24)
|
||||
}
|
||||
}
|
||||
}
|
||||
return [howLong, qualifier]
|
||||
}
|
||||
|
||||
function getTabInfo(session) {
|
||||
let tab
|
||||
let extraInfo
|
||||
if (session.tab) {
|
||||
tab = session.tab
|
||||
extraInfo = tab.url
|
||||
} else {
|
||||
tab = session.window.tabs.sort(
|
||||
(a, b) => b.lastAccessed - a.lastAccessed,
|
||||
)[0]
|
||||
const tabCount = session.window.tabs.length
|
||||
if (tabCount < 2) {
|
||||
extraInfo = tab.url
|
||||
} else {
|
||||
extraInfo = `${tabCount - 1} more tab${tabCount > 2 ? "s" : ""}.`
|
||||
}
|
||||
}
|
||||
return [tab, extraInfo]
|
||||
}
|
||||
|
||||
class SessionCompletionOption extends Completions.CompletionOptionHTML
|
||||
implements Completions.CompletionOptionFuse {
|
||||
public fuseKeys = []
|
||||
|
||||
constructor(public session) {
|
||||
super()
|
||||
this.value = (session.tab || session.window).sessionId
|
||||
const [howLong, qualifier] = computeDate(session)
|
||||
const [tab, extraInfo] = getTabInfo(session)
|
||||
this.fuseKeys.push(tab.title)
|
||||
this.html = html`<tr class="SessionCompletionOption option">
|
||||
<td class="type">${session.tab ? "T" : "W"}</td>
|
||||
<td class="time">${howLong}${qualifier}</td>
|
||||
<td class="icon"><img src="${tab.favIconUrl ||
|
||||
Completions.DEFAULT_FAVICON}"/></td>
|
||||
<td class="title">${tab.title}</td>
|
||||
<td class="extraInfo">${extraInfo}</td>
|
||||
</tr>`
|
||||
}
|
||||
}
|
||||
|
||||
export class SessionsCompletionSource extends Completions.CompletionSourceFuse {
|
||||
public options: SessionCompletionOption[]
|
||||
private shouldSetStateFromScore = true
|
||||
|
||||
constructor(private _parent) {
|
||||
super(["undo"], "SessionCompletionSource", "sessions")
|
||||
|
||||
this.updateOptions()
|
||||
this._parent.appendChild(this.node)
|
||||
}
|
||||
|
||||
private async updateOptions(exstr = "") {
|
||||
const [prefix, query] = this.splitOnPrefix(exstr)
|
||||
const sessions = await browserBg.sessions.getRecentlyClosed()
|
||||
this.options = sessions.map(s => new SessionCompletionOption(s))
|
||||
}
|
||||
|
||||
async onInput(exstr) {
|
||||
return this.updateOptions(exstr)
|
||||
}
|
||||
}
|
|
@ -2064,6 +2064,13 @@ export async function undo(item = "recent"): Promise<Number> {
|
|||
return lastSession.window.id
|
||||
}
|
||||
}
|
||||
} else if (!isNaN(parseInt(item))) {
|
||||
const sessionId = item
|
||||
const session = sessions.find(s => (s.tab || s.window).sessionId == sessionId)
|
||||
if (session) {
|
||||
browser.sessions.restore(sessionId)
|
||||
return (session.tab || session.window).id
|
||||
}
|
||||
} else {
|
||||
throw new Error(`[undo] Invalid argument: ${item}. Must be one of "tab", "window", "recent"`)
|
||||
}
|
||||
|
|
|
@ -240,3 +240,14 @@ a.url:hover {
|
|||
.HelpCompletionOption td.name {
|
||||
max-width: 25%;
|
||||
}
|
||||
|
||||
#completions .SessionCompletionOption td.type {
|
||||
width: 1ch !important;
|
||||
padding: 0px 3pt;
|
||||
}
|
||||
|
||||
#completions .SessionCompletionOption td.time {
|
||||
width: 5ch !important;
|
||||
padding: 0px 3pt;
|
||||
text-align: right;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue