Add recents section

This commit is contained in:
Asher 2020-03-02 11:52:39 -06:00
parent 88cab27165
commit c146457de4
No known key found for this signature in database
GPG Key ID: D63C1EF81242354A
4 changed files with 53 additions and 20 deletions

View File

@ -30,6 +30,16 @@
</div> </div>
</div> </div>
<div class="card-box">
<div class="header">
<h2 class="main">Recent</h2>
<div class="sub">Choose a recent directory or workspace to launch below.</div>
</div>
<div class="content">
{{APP_LIST:RECENT_PROJECTS}}
</div>
</div>
<div class="card-box"> <div class="card-box">
<div class="header"> <div class="header">
<h2 class="main">Editors</h2> <h2 class="main">Editors</h2>

View File

@ -34,6 +34,7 @@ export interface SessionResponse {
export interface RecentResponse { export interface RecentResponse {
readonly paths: string[] readonly paths: string[]
readonly workspaces: string[]
} }
export interface RunningResponse { export interface RunningResponse {

View File

@ -28,7 +28,7 @@ interface ServerSession {
} }
interface VsRecents { interface VsRecents {
[key: string]: (string | object)[] [key: string]: (string | { configURIPath: string })[]
} }
type VsSettings = [string, string][] type VsSettings = [string, string][]
@ -322,28 +322,34 @@ export class ApiHttpProvider extends HttpProvider {
throw new Error("settings appear malformed") throw new Error("settings appear malformed")
} }
const paths: { [key: string]: Promise<string> } = {} const pathPromises: { [key: string]: Promise<string> } = {}
const workspacePromises: { [key: string]: Promise<string> } = {}
Object.values(JSON.parse(setting[1]) as VsRecents).forEach((recents) => { Object.values(JSON.parse(setting[1]) as VsRecents).forEach((recents) => {
recents recents.forEach((recent) => {
.filter((recent) => typeof recent === "string") try {
.forEach((recent) => { const target = typeof recent === "string" ? pathPromises : workspacePromises
try { const pathname = url.parse(typeof recent === "string" ? recent : recent.configURIPath).pathname
const pathname = url.parse(recent as string).pathname if (pathname && !target[pathname]) {
if (pathname && !paths[pathname]) { target[pathname] = new Promise<string>((resolve) => {
paths[pathname] = new Promise<string>((resolve) => { fs.stat(pathname)
fs.stat(pathname) .then(() => resolve(pathname))
.then(() => resolve(pathname)) .catch(() => resolve())
.catch(() => resolve()) })
})
}
} catch (error) {
logger.debug("invalid path", field("path", recent))
} }
}) } catch (error) {
logger.debug("invalid path", field("path", recent))
}
})
}) })
const [paths, workspaces] = await Promise.all([
Promise.all(Object.values(pathPromises)),
Promise.all(Object.values(workspacePromises)),
])
return { return {
paths: await Promise.all(Object.values(paths)), paths: paths.filter((p) => !!p),
workspaces: workspaces.filter((p) => !!p),
} }
} catch (error) { } catch (error) {
if (error.code !== "ENOENT") { if (error.code !== "ENOENT") {
@ -351,7 +357,7 @@ export class ApiHttpProvider extends HttpProvider {
} }
} }
return { paths: [] } return { paths: [], workspaces: [] }
} }
/** /**

View File

@ -1,6 +1,6 @@
import * as http from "http" import * as http from "http"
import * as querystring from "querystring" import * as querystring from "querystring"
import { Application } from "../../common/api" import { Application, RecentResponse } from "../../common/api"
import { HttpCode, HttpError } from "../../common/http" import { HttpCode, HttpError } from "../../common/http"
import { HttpProvider, HttpProviderOptions, HttpResponse, Route } from "../http" import { HttpProvider, HttpProviderOptions, HttpResponse, Route } from "../http"
import { ApiHttpProvider } from "./api" import { ApiHttpProvider } from "./api"
@ -86,6 +86,7 @@ export class MainHttpProvider extends HttpProvider {
response.content = response.content response.content = response.content
.replace(/{{UPDATE:NAME}}/, await this.getUpdate()) .replace(/{{UPDATE:NAME}}/, await this.getUpdate())
.replace(/{{APP_LIST:RUNNING}}/, this.getAppRows(running.applications)) .replace(/{{APP_LIST:RUNNING}}/, this.getAppRows(running.applications))
.replace(/{{APP_LIST:RECENT_PROJECTS}}/, this.getRecentProjectRows(await this.api.recent()))
.replace( .replace(
/{{APP_LIST:EDITORS}}/, /{{APP_LIST:EDITORS}}/,
this.getAppRows(apps.filter((app) => app.categories && app.categories.includes("Editor"))), this.getAppRows(apps.filter((app) => app.categories && app.categories.includes("Editor"))),
@ -107,6 +108,21 @@ export class MainHttpProvider extends HttpProvider {
return undefined return undefined
} }
private getRecentProjectRows(recents: RecentResponse): string {
return recents.paths.length > 0 || recents.workspaces.length > 0
? recents.paths.map((recent) => this.getRecentProjectRow(recent)).join("\n") +
recents.workspaces.map((recent) => this.getRecentProjectRow(recent, true)).join("\n")
: `<div class="none">No recent directories or workspaces.</div>`
}
private getRecentProjectRow(recent: string, workspace?: boolean): string {
return `<div class="block-row">
<a class="item -row -link" href="./vscode/?${workspace ? "workspace" : "folder"}=${recent}">
<div class="name">${recent}${workspace ? " (workspace)" : ""}</div>
</a>
</div>`
}
private getAppRows(apps: ReadonlyArray<Application>): string { private getAppRows(apps: ReadonlyArray<Application>): string {
return apps.length > 0 return apps.length > 0
? apps.map((app) => this.getAppRow(app)).join("\n") ? apps.map((app) => this.getAppRow(app)).join("\n")