@davmash/bygone 0.8.6 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +6 -0
- package/cli/present.js +26 -0
- package/docs/present.md +32 -0
- package/docs/product-surface.md +1 -0
- package/media/webview.css +1 -1
- package/out/standalone-main.js +254 -6
- package/package.json +1 -1
- package/standalone/index.html +13 -5
- package/web/index.html +41 -5
- package/web/presenter.css +136 -0
- package/web/web-host.js +5 -5
package/out/standalone-main.js
CHANGED
|
@@ -8772,6 +8772,20 @@ var require_present = __commonJS({
|
|
|
8772
8772
|
let presenterIndexTemplate;
|
|
8773
8773
|
const server = createServer((request, response) => {
|
|
8774
8774
|
const requestUrl = new URL(request.url || "/", "http://127.0.0.1");
|
|
8775
|
+
if (requestUrl.pathname === "/narration/claim") {
|
|
8776
|
+
if (request.method !== "POST") {
|
|
8777
|
+
respond(response, 405, "Method not allowed");
|
|
8778
|
+
return;
|
|
8779
|
+
}
|
|
8780
|
+
if (!isSameOriginLoopbackRequest(request)) {
|
|
8781
|
+
respond(response, 403, "Forbidden");
|
|
8782
|
+
return;
|
|
8783
|
+
}
|
|
8784
|
+
options.onNarrationClaim?.();
|
|
8785
|
+
response.writeHead(204, { "Cache-Control": "no-store" });
|
|
8786
|
+
response.end();
|
|
8787
|
+
return;
|
|
8788
|
+
}
|
|
8775
8789
|
if (requestUrl.pathname === "/tour.json") {
|
|
8776
8790
|
response.writeHead(200, {
|
|
8777
8791
|
"Content-Type": "application/json; charset=utf-8",
|
|
@@ -8897,6 +8911,17 @@ var require_present = __commonJS({
|
|
|
8897
8911
|
}
|
|
8898
8912
|
response.end(message);
|
|
8899
8913
|
}
|
|
8914
|
+
function isSameOriginLoopbackRequest(request) {
|
|
8915
|
+
const origin = request.headers.origin;
|
|
8916
|
+
const host = request.headers.host;
|
|
8917
|
+
if (typeof origin !== "string" || typeof host !== "string") return false;
|
|
8918
|
+
try {
|
|
8919
|
+
const parsed = new URL(origin);
|
|
8920
|
+
return parsed.protocol === "http:" && parsed.hostname === "127.0.0.1" && parsed.host === host;
|
|
8921
|
+
} catch {
|
|
8922
|
+
return false;
|
|
8923
|
+
}
|
|
8924
|
+
}
|
|
8900
8925
|
function escapeHtml(text) {
|
|
8901
8926
|
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
8902
8927
|
}
|
|
@@ -8951,6 +8976,116 @@ var require_launchArgs = __commonJS({
|
|
|
8951
8976
|
}
|
|
8952
8977
|
});
|
|
8953
8978
|
|
|
8979
|
+
// standalone/windowState.js
|
|
8980
|
+
var require_windowState = __commonJS({
|
|
8981
|
+
"standalone/windowState.js"(exports2, module2) {
|
|
8982
|
+
"use strict";
|
|
8983
|
+
var fs8 = require("fs");
|
|
8984
|
+
var path9 = require("path");
|
|
8985
|
+
var WINDOW_STATE_VERSION = 1;
|
|
8986
|
+
function readWindowState2(filePath) {
|
|
8987
|
+
try {
|
|
8988
|
+
return normalizeWindowState(JSON.parse(fs8.readFileSync(filePath, "utf8")));
|
|
8989
|
+
} catch {
|
|
8990
|
+
return null;
|
|
8991
|
+
}
|
|
8992
|
+
}
|
|
8993
|
+
function writeWindowState2(filePath, state) {
|
|
8994
|
+
const normalized = normalizeWindowState(state);
|
|
8995
|
+
if (!normalized) {
|
|
8996
|
+
throw new Error("Cannot save invalid Bygone window state.");
|
|
8997
|
+
}
|
|
8998
|
+
fs8.mkdirSync(path9.dirname(filePath), { recursive: true });
|
|
8999
|
+
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
9000
|
+
try {
|
|
9001
|
+
fs8.writeFileSync(temporaryPath, `${JSON.stringify(normalized, null, 2)}
|
|
9002
|
+
`, "utf8");
|
|
9003
|
+
fs8.renameSync(temporaryPath, filePath);
|
|
9004
|
+
} finally {
|
|
9005
|
+
try {
|
|
9006
|
+
fs8.unlinkSync(temporaryPath);
|
|
9007
|
+
} catch {
|
|
9008
|
+
}
|
|
9009
|
+
}
|
|
9010
|
+
}
|
|
9011
|
+
function normalizeWindowState(value) {
|
|
9012
|
+
if (!value || typeof value !== "object" || value.version !== WINDOW_STATE_VERSION) {
|
|
9013
|
+
return null;
|
|
9014
|
+
}
|
|
9015
|
+
const mainSource = value.main === null ? null : normalizeSessionSource(value.main?.source);
|
|
9016
|
+
if (value.main !== null && !mainSource) {
|
|
9017
|
+
return null;
|
|
9018
|
+
}
|
|
9019
|
+
if (!Array.isArray(value.tours)) {
|
|
9020
|
+
return null;
|
|
9021
|
+
}
|
|
9022
|
+
const tours = value.tours.map(normalizeTourLaunch).filter(Boolean);
|
|
9023
|
+
if (tours.length !== value.tours.length) {
|
|
9024
|
+
return null;
|
|
9025
|
+
}
|
|
9026
|
+
return {
|
|
9027
|
+
version: WINDOW_STATE_VERSION,
|
|
9028
|
+
main: mainSource ? { source: mainSource } : null,
|
|
9029
|
+
tours
|
|
9030
|
+
};
|
|
9031
|
+
}
|
|
9032
|
+
function normalizeSessionSource(source) {
|
|
9033
|
+
if (!source || typeof source !== "object" || typeof source.kind !== "string") {
|
|
9034
|
+
return null;
|
|
9035
|
+
}
|
|
9036
|
+
if (source.kind === "blank") {
|
|
9037
|
+
return { kind: "blank" };
|
|
9038
|
+
}
|
|
9039
|
+
if (source.kind === "files" || source.kind === "directories") {
|
|
9040
|
+
if (!isStringArray(source.paths) || source.paths.length === 0) return null;
|
|
9041
|
+
return {
|
|
9042
|
+
kind: source.kind,
|
|
9043
|
+
paths: [...source.paths],
|
|
9044
|
+
...source.kind === "directories" && isStringArray(source.labels) ? { labels: [...source.labels] } : {}
|
|
9045
|
+
};
|
|
9046
|
+
}
|
|
9047
|
+
if (source.kind === "file-history" || source.kind === "directory-history") {
|
|
9048
|
+
if (typeof source.path !== "string" || source.path.length === 0) return null;
|
|
9049
|
+
return {
|
|
9050
|
+
kind: source.kind,
|
|
9051
|
+
path: source.path,
|
|
9052
|
+
includeStaged: Boolean(source.includeStaged),
|
|
9053
|
+
skipUnchanged: Boolean(source.skipUnchanged)
|
|
9054
|
+
};
|
|
9055
|
+
}
|
|
9056
|
+
if (source.kind === "git-refs") {
|
|
9057
|
+
if (typeof source.repoRoot !== "string" || !isStringArray(source.refs) || source.refs.length < 2) return null;
|
|
9058
|
+
return { kind: source.kind, repoRoot: source.repoRoot, refs: [...source.refs] };
|
|
9059
|
+
}
|
|
9060
|
+
if (source.kind === "branch-review") {
|
|
9061
|
+
if (typeof source.repoRoot !== "string" || typeof source.headRef !== "string") return null;
|
|
9062
|
+
return {
|
|
9063
|
+
kind: source.kind,
|
|
9064
|
+
repoRoot: source.repoRoot,
|
|
9065
|
+
headRef: source.headRef,
|
|
9066
|
+
...typeof source.baseRef === "string" ? { baseRef: source.baseRef } : {}
|
|
9067
|
+
};
|
|
9068
|
+
}
|
|
9069
|
+
return null;
|
|
9070
|
+
}
|
|
9071
|
+
function normalizeTourLaunch(value) {
|
|
9072
|
+
if (!value || typeof value !== "object" || !isStringArray(value.args) || typeof value.cwd !== "string") {
|
|
9073
|
+
return null;
|
|
9074
|
+
}
|
|
9075
|
+
return { args: [...value.args], cwd: value.cwd };
|
|
9076
|
+
}
|
|
9077
|
+
function isStringArray(value) {
|
|
9078
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
9079
|
+
}
|
|
9080
|
+
module2.exports = {
|
|
9081
|
+
WINDOW_STATE_VERSION,
|
|
9082
|
+
normalizeWindowState,
|
|
9083
|
+
readWindowState: readWindowState2,
|
|
9084
|
+
writeWindowState: writeWindowState2
|
|
9085
|
+
};
|
|
9086
|
+
}
|
|
9087
|
+
});
|
|
9088
|
+
|
|
8954
9089
|
// src/windowTitle.ts
|
|
8955
9090
|
var windowTitle_exports = {};
|
|
8956
9091
|
__export(windowTitle_exports, {
|
|
@@ -9075,7 +9210,7 @@ var require_package = __commonJS({
|
|
|
9075
9210
|
displayName: "Bygone",
|
|
9076
9211
|
desktopName: "com.davidmashburn.bygone.desktop",
|
|
9077
9212
|
description: "See how change happened. Visual diff and file history for VS Code.",
|
|
9078
|
-
version: "0.8.
|
|
9213
|
+
version: "0.8.7",
|
|
9079
9214
|
author: "David Mashburn",
|
|
9080
9215
|
license: "MIT",
|
|
9081
9216
|
private: false,
|
|
@@ -22324,6 +22459,7 @@ var { tokenMatches, tokensFor } = require_commandSpec();
|
|
|
22324
22459
|
var { startPresentation } = require_present();
|
|
22325
22460
|
var { resolveWorkingDirectory } = require_workingDirectory();
|
|
22326
22461
|
var { getCliArgsFromArgv, getForwardedLaunchArgs } = require_launchArgs();
|
|
22462
|
+
var { readWindowState, writeWindowState } = require_windowState();
|
|
22327
22463
|
var {
|
|
22328
22464
|
buildHistoryTitle: buildHistoryTitle2,
|
|
22329
22465
|
buildStandaloneSessionTitle: buildStandaloneSessionTitle2,
|
|
@@ -22343,13 +22479,15 @@ var parsedDirectoryHistoryCacheSize = Number.parseInt(process.env.BYGONE_DIR_HIS
|
|
|
22343
22479
|
var DIRECTORY_HISTORY_CACHE_SIZE = Number.isFinite(parsedDirectoryHistoryCacheSize) && parsedDirectoryHistoryCacheSize > 0 ? parsedDirectoryHistoryCacheSize : DEFAULT_DIRECTORY_HISTORY_CACHE_SIZE;
|
|
22344
22480
|
var commandLineToolPath = process.platform === "win32" ? path8.join(process.env.LOCALAPPDATA || os.homedir(), "Microsoft", "WindowsApps", "bygone.cmd") : "/usr/local/bin/bygone";
|
|
22345
22481
|
var gitHistoryService = new GitHistoryService2();
|
|
22346
|
-
var
|
|
22482
|
+
var initialCliArgs = getCliArgs();
|
|
22483
|
+
var launchArguments = parseLaunchArgs(initialCliArgs);
|
|
22347
22484
|
var smokeTestMode = launchArguments.kind === "smoke" || launchArguments.kind === "smoke-multi" || launchArguments.kind === "smoke-directory";
|
|
22348
22485
|
var captureOutputPath = launchArguments.capturePath ? path8.resolve(launchArguments.capturePath) : null;
|
|
22349
22486
|
var captureMode = Boolean(captureOutputPath);
|
|
22350
22487
|
var launchWindowWidth = Number.isFinite(launchArguments.windowWidth) ? launchArguments.windowWidth : 1500;
|
|
22351
22488
|
var launchWindowHeight = Number.isFinite(launchArguments.windowHeight) ? launchArguments.windowHeight : 960;
|
|
22352
22489
|
var shouldUseSingleInstanceLock = app.isPackaged && !smokeTestMode && !captureMode;
|
|
22490
|
+
var shouldRestoreWindowState = initialCliArgs.length === 0 && !smokeTestMode && !captureMode;
|
|
22353
22491
|
app.setName(APP_NAME);
|
|
22354
22492
|
if (typeof app.setAppUserModelId === "function") {
|
|
22355
22493
|
app.setAppUserModelId("com.davidmashburn.bygone");
|
|
@@ -22383,6 +22521,8 @@ var wordWrapEnabled = false;
|
|
|
22383
22521
|
var wordWrapAvailable = false;
|
|
22384
22522
|
var repositorySearch = null;
|
|
22385
22523
|
var lastRepositoryReplacement = null;
|
|
22524
|
+
var appIsQuitting = false;
|
|
22525
|
+
var restoringWindowState = false;
|
|
22386
22526
|
if (!singleInstanceLock) {
|
|
22387
22527
|
app.quit();
|
|
22388
22528
|
}
|
|
@@ -22399,6 +22539,10 @@ app.on("window-all-closed", () => {
|
|
|
22399
22539
|
app.quit();
|
|
22400
22540
|
}
|
|
22401
22541
|
});
|
|
22542
|
+
app.on("before-quit", () => {
|
|
22543
|
+
appIsQuitting = true;
|
|
22544
|
+
persistOpenWindowState();
|
|
22545
|
+
});
|
|
22402
22546
|
app.on("will-quit", () => {
|
|
22403
22547
|
repositorySearch?.handle?.cancel();
|
|
22404
22548
|
for (const server of [...activeTourServers]) {
|
|
@@ -22548,6 +22692,9 @@ function createMainWindow({ show = !smokeTestMode } = {}) {
|
|
|
22548
22692
|
smokeTimeout = void 0;
|
|
22549
22693
|
captureScheduled = false;
|
|
22550
22694
|
captureRenderReady = false;
|
|
22695
|
+
if (!appIsQuitting && (process.platform === "darwin" || BrowserWindow.getAllWindows().length > 0)) {
|
|
22696
|
+
persistOpenWindowState();
|
|
22697
|
+
}
|
|
22551
22698
|
});
|
|
22552
22699
|
}
|
|
22553
22700
|
function ensureMainWindow() {
|
|
@@ -22557,13 +22704,18 @@ function ensureMainWindow() {
|
|
|
22557
22704
|
}
|
|
22558
22705
|
}
|
|
22559
22706
|
async function openTourPresentation(args, cwd) {
|
|
22707
|
+
let ownerWindow = null;
|
|
22560
22708
|
const presentation = await startPresentation(args, cwd, packageRoot, {
|
|
22561
22709
|
announce: false,
|
|
22562
|
-
open: false
|
|
22710
|
+
open: false,
|
|
22711
|
+
onNarrationClaim: () => claimTourNarration(ownerWindow)
|
|
22563
22712
|
});
|
|
22564
22713
|
activeTourServers.add(presentation.server);
|
|
22565
22714
|
try {
|
|
22566
|
-
await showTourWindow(presentation.url, presentation.server, presentation.manifest
|
|
22715
|
+
ownerWindow = await showTourWindow(presentation.url, presentation.server, presentation.manifest, {
|
|
22716
|
+
args: [...args],
|
|
22717
|
+
cwd: path8.resolve(cwd)
|
|
22718
|
+
});
|
|
22567
22719
|
} catch (error) {
|
|
22568
22720
|
closeTourServer(presentation.server);
|
|
22569
22721
|
throw error;
|
|
@@ -22573,7 +22725,7 @@ async function openAuthoredTourDocument(sourcePath) {
|
|
|
22573
22725
|
const document2 = discoverAuthoredTourDocument2(sourcePath);
|
|
22574
22726
|
await openTourPresentation(["--tour", document2.documentPath], document2.repoRoot);
|
|
22575
22727
|
}
|
|
22576
|
-
async function showTourWindow(url, server, manifest) {
|
|
22728
|
+
async function showTourWindow(url, server, manifest, launch) {
|
|
22577
22729
|
const parsedUrl = new URL(url);
|
|
22578
22730
|
if (parsedUrl.protocol !== "http:" || parsedUrl.hostname !== "127.0.0.1") {
|
|
22579
22731
|
throw new Error("Tour presenter URL must use the local Bygone server.");
|
|
@@ -22595,7 +22747,8 @@ async function showTourWindow(url, server, manifest) {
|
|
|
22595
22747
|
}
|
|
22596
22748
|
});
|
|
22597
22749
|
latestTourWindow = tourWindow;
|
|
22598
|
-
tourPresentations.set(tourWindow, { server, origin: tourOrigin });
|
|
22750
|
+
tourPresentations.set(tourWindow, { server, origin: tourOrigin, launch });
|
|
22751
|
+
installApplicationMenu();
|
|
22599
22752
|
tourWindow.webContents.setWindowOpenHandler(({ url: externalUrl }) => {
|
|
22600
22753
|
if (/^https?:\/\//i.test(externalUrl)) {
|
|
22601
22754
|
void shell.openExternal(externalUrl);
|
|
@@ -22622,6 +22775,10 @@ async function showTourWindow(url, server, manifest) {
|
|
|
22622
22775
|
if (latestTourWindow === tourWindow) {
|
|
22623
22776
|
latestTourWindow = getLatestTourWindow();
|
|
22624
22777
|
}
|
|
22778
|
+
installApplicationMenu();
|
|
22779
|
+
if (!appIsQuitting && (process.platform === "darwin" || BrowserWindow.getAllWindows().length > 0)) {
|
|
22780
|
+
persistOpenWindowState();
|
|
22781
|
+
}
|
|
22625
22782
|
});
|
|
22626
22783
|
const tourWindowTitle = buildTourWindowTitle2(manifest, APP_NAME);
|
|
22627
22784
|
const applyTourWindowTitle = () => {
|
|
@@ -22643,11 +22800,30 @@ async function showTourWindow(url, server, manifest) {
|
|
|
22643
22800
|
applyTourWindowTitle();
|
|
22644
22801
|
tourWindow.show();
|
|
22645
22802
|
tourWindow.focus();
|
|
22803
|
+
persistOpenWindowState();
|
|
22646
22804
|
return tourWindow;
|
|
22647
22805
|
}
|
|
22648
22806
|
function getLatestTourWindow() {
|
|
22649
22807
|
return [...tourPresentations.keys()].reverse().find((window2) => !window2.isDestroyed());
|
|
22650
22808
|
}
|
|
22809
|
+
function claimTourNarration(ownerWindow) {
|
|
22810
|
+
if (!ownerWindow || ownerWindow.isDestroyed()) return;
|
|
22811
|
+
for (const tourWindow of tourPresentations.keys()) {
|
|
22812
|
+
if (tourWindow !== ownerWindow && !tourWindow.isDestroyed()) {
|
|
22813
|
+
dispatchTourPresenterCommand(tourWindow, "pauseNarration");
|
|
22814
|
+
}
|
|
22815
|
+
}
|
|
22816
|
+
}
|
|
22817
|
+
function dispatchTourPresenterCommand(tourWindow, command) {
|
|
22818
|
+
if (!tourWindow || tourWindow.isDestroyed()) return;
|
|
22819
|
+
const script = `window.dispatchEvent(new CustomEvent('bygone:tour-command', { detail: ${JSON.stringify(command)} }))`;
|
|
22820
|
+
void tourWindow.webContents.executeJavaScript(script).catch(() => {
|
|
22821
|
+
});
|
|
22822
|
+
}
|
|
22823
|
+
function toggleLatestTourNarration() {
|
|
22824
|
+
const tourWindow = getLatestTourWindow();
|
|
22825
|
+
if (tourWindow) dispatchTourPresenterCommand(tourWindow, "toggleNarration");
|
|
22826
|
+
}
|
|
22651
22827
|
function closeTourServer(server) {
|
|
22652
22828
|
if (!server || !activeTourServers.delete(server)) {
|
|
22653
22829
|
return;
|
|
@@ -22962,6 +23138,12 @@ ${HELP_URL}`,
|
|
|
22962
23138
|
click: () => {
|
|
22963
23139
|
void openAuthoredTourDialog().catch((error) => showError(`Could not open Bygone presentation: ${getErrorMessage(error)}`));
|
|
22964
23140
|
}
|
|
23141
|
+
},
|
|
23142
|
+
{ type: "separator" },
|
|
23143
|
+
{
|
|
23144
|
+
label: "Listen to Tour",
|
|
23145
|
+
enabled: Boolean(getLatestTourWindow()),
|
|
23146
|
+
click: toggleLatestTourNarration
|
|
22965
23147
|
}
|
|
22966
23148
|
]
|
|
22967
23149
|
},
|
|
@@ -23320,8 +23502,73 @@ async function openInitialLaunchTarget() {
|
|
|
23320
23502
|
await routePendingOpenPaths();
|
|
23321
23503
|
return;
|
|
23322
23504
|
}
|
|
23505
|
+
if (shouldRestoreWindowState && await restoreOpenWindowState()) {
|
|
23506
|
+
return;
|
|
23507
|
+
}
|
|
23323
23508
|
await routeLaunchTarget(launchArguments);
|
|
23324
23509
|
}
|
|
23510
|
+
async function restoreOpenWindowState() {
|
|
23511
|
+
const savedState = readWindowState(getWindowStatePath());
|
|
23512
|
+
if (!savedState || !savedState.main && savedState.tours.length === 0) {
|
|
23513
|
+
return false;
|
|
23514
|
+
}
|
|
23515
|
+
let restoredAnyWindow = false;
|
|
23516
|
+
restoringWindowState = true;
|
|
23517
|
+
try {
|
|
23518
|
+
if (savedState.main) {
|
|
23519
|
+
ensureMainWindow();
|
|
23520
|
+
try {
|
|
23521
|
+
await restoreMainSession(savedState.main.source);
|
|
23522
|
+
} catch (error) {
|
|
23523
|
+
console.error(`Could not restore the previous Bygone session: ${getErrorMessage(error)}`);
|
|
23524
|
+
await openBlankDiff();
|
|
23525
|
+
}
|
|
23526
|
+
restoredAnyWindow = true;
|
|
23527
|
+
}
|
|
23528
|
+
for (const tour of savedState.tours) {
|
|
23529
|
+
try {
|
|
23530
|
+
await openTourPresentation(tour.args, tour.cwd);
|
|
23531
|
+
restoredAnyWindow = true;
|
|
23532
|
+
} catch (error) {
|
|
23533
|
+
console.error(`Could not restore a previous Bygone tour: ${getErrorMessage(error)}`);
|
|
23534
|
+
}
|
|
23535
|
+
}
|
|
23536
|
+
} finally {
|
|
23537
|
+
restoringWindowState = false;
|
|
23538
|
+
persistOpenWindowState();
|
|
23539
|
+
}
|
|
23540
|
+
return restoredAnyWindow;
|
|
23541
|
+
}
|
|
23542
|
+
async function restoreMainSession(source) {
|
|
23543
|
+
if (source.kind === "blank") {
|
|
23544
|
+
await openBlankDiff();
|
|
23545
|
+
return;
|
|
23546
|
+
}
|
|
23547
|
+
session = buildSessionFromSource(source);
|
|
23548
|
+
historyIncludeStagedPreference = Boolean(source.includeStaged ?? historyIncludeStagedPreference);
|
|
23549
|
+
historySkipUnchangedPreference = Boolean(source.skipUnchanged ?? historySkipUnchangedPreference);
|
|
23550
|
+
clearWatchers();
|
|
23551
|
+
updateWatchers();
|
|
23552
|
+
await sendCurrentSession();
|
|
23553
|
+
}
|
|
23554
|
+
function persistOpenWindowState() {
|
|
23555
|
+
if (restoringWindowState || !app.isReady()) return;
|
|
23556
|
+
const hasMainWindow = Boolean(mainWindow && !mainWindow.isDestroyed());
|
|
23557
|
+
const mainSource = hasMainWindow && (isRefreshableSource(session.source) || session.source?.kind === "blank") ? cloneSessionSource(session.source) : hasMainWindow ? { kind: "blank" } : null;
|
|
23558
|
+
const tours = [...tourPresentations.entries()].filter(([window2, presentation]) => !window2.isDestroyed() && presentation.launch).map(([, presentation]) => presentation.launch);
|
|
23559
|
+
try {
|
|
23560
|
+
writeWindowState(getWindowStatePath(), {
|
|
23561
|
+
version: 1,
|
|
23562
|
+
main: mainSource ? { source: mainSource } : null,
|
|
23563
|
+
tours
|
|
23564
|
+
});
|
|
23565
|
+
} catch (error) {
|
|
23566
|
+
console.error(`Could not save Bygone window state: ${getErrorMessage(error)}`);
|
|
23567
|
+
}
|
|
23568
|
+
}
|
|
23569
|
+
function getWindowStatePath() {
|
|
23570
|
+
return path8.join(app.getPath("userData"), "open-windows.json");
|
|
23571
|
+
}
|
|
23325
23572
|
async function routeLaunchTarget(launchTarget) {
|
|
23326
23573
|
if (launchTarget.kind === "unsupported-launch-intent") {
|
|
23327
23574
|
ensureMainWindow();
|
|
@@ -26928,6 +27175,7 @@ async function refreshSession(options = {}) {
|
|
|
26928
27175
|
function postOrQueue(message) {
|
|
26929
27176
|
installApplicationMenu();
|
|
26930
27177
|
if (message && typeof message === "object" && typeof message.type === "string" && message.type.startsWith("show")) {
|
|
27178
|
+
persistOpenWindowState();
|
|
26931
27179
|
if (!refreshInProgress) {
|
|
26932
27180
|
refreshFailure = null;
|
|
26933
27181
|
}
|
package/package.json
CHANGED
package/standalone/index.html
CHANGED
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
<div id="change-toolbar" class="change-toolbar header-align-diff" hidden>
|
|
31
31
|
<div class="change-toolbar-main">
|
|
32
32
|
<div class="change-toolbar-nav">
|
|
33
|
-
<button id="previous-file" class="change-button icon-button" type="button" title="Open previous file" aria-label="Previous file">
|
|
33
|
+
<button id="previous-file" class="change-button icon-button" type="button" title="Open previous file" data-tooltip="Open previous file" aria-label="Previous file">
|
|
34
34
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
35
35
|
<path d="M17 11l-5-5-5 5"></path>
|
|
36
36
|
<path d="M17 18l-5-5-5 5" opacity="0.7"></path>
|
|
37
37
|
</svg>
|
|
38
38
|
</button>
|
|
39
|
-
<button id="next-file" class="change-button change-button-primary icon-button" type="button" title="Open next file" aria-label="Next file">
|
|
39
|
+
<button id="next-file" class="change-button change-button-primary icon-button" type="button" title="Open next file" data-tooltip="Open next file" aria-label="Next file">
|
|
40
40
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
41
41
|
<path d="M7 13l5 5 5-5"></path>
|
|
42
42
|
<path d="M7 6l5 5 5-5" opacity="0.7"></path>
|
|
@@ -72,8 +72,15 @@
|
|
|
72
72
|
</svg>
|
|
73
73
|
</button>
|
|
74
74
|
</div>
|
|
75
|
+
<div class="change-toolbar-actions">
|
|
75
76
|
<button id="toggle-word-wrap" class="change-button icon-button" type="button" title="Enable line wrapping (Alt+Z)" aria-label="Enable line wrapping" aria-pressed="false" hidden>
|
|
76
|
-
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
77
|
+
<svg class="word-wrap-icon-off" viewBox="0 0 24 24" aria-hidden="true">
|
|
78
|
+
<path d="M4 6h13a3 3 0 0 1 0 6H9"></path>
|
|
79
|
+
<path d="M12 9l-3 3 3 3"></path>
|
|
80
|
+
<path d="M4 18h8"></path>
|
|
81
|
+
<path d="M5 4l14 16"></path>
|
|
82
|
+
</svg>
|
|
83
|
+
<svg class="word-wrap-icon-on" viewBox="0 0 24 24" aria-hidden="true">
|
|
77
84
|
<path d="M4 6h13a3 3 0 0 1 0 6H9"></path>
|
|
78
85
|
<path d="M12 9l-3 3 3 3"></path>
|
|
79
86
|
<path d="M4 18h8"></path>
|
|
@@ -85,6 +92,7 @@
|
|
|
85
92
|
<path d="M20 5v6h-6"></path>
|
|
86
93
|
</svg>
|
|
87
94
|
</button>
|
|
95
|
+
</div>
|
|
88
96
|
</div>
|
|
89
97
|
<div class="change-hint">F7 / Shift+F7 · Cmd/Ctrl+Shift+Up/Down to jump.</div>
|
|
90
98
|
</div>
|
|
@@ -94,14 +102,14 @@
|
|
|
94
102
|
<div id="history-left-time" class="history-time"></div>
|
|
95
103
|
</div>
|
|
96
104
|
<div class="history-nav">
|
|
97
|
-
<button id="history-back" class="history-button icon-button" type="button" title="Open older commit (Alt+Left)" aria-label="Older commit">
|
|
105
|
+
<button id="history-back" class="history-button icon-button" type="button" title="Open older commit (Alt+Left)" data-tooltip="Open older commit" aria-label="Older commit">
|
|
98
106
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
99
107
|
<path d="M15 18l-6-6 6-6"></path>
|
|
100
108
|
<path d="M10 18l-6-6 6-6" opacity="0.7"></path>
|
|
101
109
|
</svg>
|
|
102
110
|
</button>
|
|
103
111
|
<div id="history-position" class="history-position" role="status" aria-live="polite" aria-atomic="true"></div>
|
|
104
|
-
<button id="history-forward" class="history-button icon-button" type="button" title="Open newer commit (Alt+Right)" aria-label="Newer commit">
|
|
112
|
+
<button id="history-forward" class="history-button icon-button" type="button" title="Open newer commit (Alt+Right)" data-tooltip="Open newer commit" aria-label="Newer commit">
|
|
105
113
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
106
114
|
<path d="M9 18l6-6-6-6"></path>
|
|
107
115
|
<path d="M14 18l6-6-6-6" opacity="0.7"></path>
|
package/web/index.html
CHANGED
|
@@ -60,6 +60,34 @@
|
|
|
60
60
|
<span id="tour-breadcrumb" class="tour-breadcrumb"></span>
|
|
61
61
|
<button id="tour-next" type="button" title="Next tour item (Right or Page Down)">Next →</button>
|
|
62
62
|
</nav>
|
|
63
|
+
<div id="tour-narration-controls" class="tour-narration-controls" role="group" aria-label="Tour narration">
|
|
64
|
+
<div class="tour-narration-transport" role="group" aria-label="Narration playback">
|
|
65
|
+
<button id="tour-narration-skip-back" type="button" title="Previous sentence" aria-label="Previous sentence" disabled>
|
|
66
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M3 12a9 9 0 1 0 3-6.7L3 8"/><path d="M3 3v5h5"/></svg>
|
|
67
|
+
</button>
|
|
68
|
+
<button id="tour-listen" type="button" title="Listen from the current tour item" aria-label="Listen from the current tour item">
|
|
69
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path class="tour-icon-fill tour-play-pause-icon" d="m8 5 11 7-11 7Z"/></svg>
|
|
70
|
+
</button>
|
|
71
|
+
<button id="tour-stop" type="button" title="Stop narration" aria-label="Stop narration" disabled>
|
|
72
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path class="tour-icon-fill" d="M6 6h12v12H6z"/></svg>
|
|
73
|
+
</button>
|
|
74
|
+
<button id="tour-narration-skip-ahead" type="button" title="Next sentence" aria-label="Next sentence" disabled>
|
|
75
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M21 12a9 9 0 1 1-3-6.7L21 8"/><path d="M21 3v5h-5"/></svg>
|
|
76
|
+
</button>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="tour-narration-settings">
|
|
79
|
+
<select id="tour-narration-voice" aria-label="Narration voice" title="Narration voice" disabled>
|
|
80
|
+
<option value="">System default voice</option>
|
|
81
|
+
</select>
|
|
82
|
+
<select id="tour-narration-rate" aria-label="Narration speed" title="Narration speed">
|
|
83
|
+
<option value="0.75">0.75×</option>
|
|
84
|
+
<option value="1">1×</option>
|
|
85
|
+
<option value="1.25">1.25×</option>
|
|
86
|
+
<option value="1.5">1.5×</option>
|
|
87
|
+
</select>
|
|
88
|
+
</div>
|
|
89
|
+
<span id="tour-narration-status" class="tour-narration-status" role="status" aria-live="polite" aria-atomic="true">Device voice ready</span>
|
|
90
|
+
</div>
|
|
63
91
|
<div class="tour-narrative-layout">
|
|
64
92
|
<div class="tour-narrative-prose">
|
|
65
93
|
<div id="tour-narrative-chapter" class="tour-narrative-chapter"></div>
|
|
@@ -113,13 +141,13 @@
|
|
|
113
141
|
<div id="change-toolbar" class="change-toolbar header-align-diff" hidden>
|
|
114
142
|
<div class="change-toolbar-main">
|
|
115
143
|
<div class="change-toolbar-nav">
|
|
116
|
-
<button id="previous-file" class="change-button icon-button" type="button" title="Open previous file" aria-label="Previous file">
|
|
144
|
+
<button id="previous-file" class="change-button icon-button" type="button" title="Open previous file" data-tooltip="Open previous file" aria-label="Previous file">
|
|
117
145
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
118
146
|
<path d="M17 11l-5-5-5 5"></path>
|
|
119
147
|
<path d="M17 18l-5-5-5 5"></path>
|
|
120
148
|
</svg>
|
|
121
149
|
</button>
|
|
122
|
-
<button id="next-file" class="change-button icon-button" type="button" title="Open next file" aria-label="Next file">
|
|
150
|
+
<button id="next-file" class="change-button icon-button" type="button" title="Open next file" data-tooltip="Open next file" aria-label="Next file">
|
|
123
151
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
124
152
|
<path d="M7 13l5 5 5-5"></path>
|
|
125
153
|
<path d="M7 6l5 5 5-5"></path>
|
|
@@ -155,8 +183,15 @@
|
|
|
155
183
|
</svg>
|
|
156
184
|
</button>
|
|
157
185
|
</div>
|
|
186
|
+
<div class="change-toolbar-actions">
|
|
158
187
|
<button id="toggle-word-wrap" class="change-button icon-button" type="button" title="Enable line wrapping (Alt+Z)" aria-label="Enable line wrapping" aria-pressed="false" hidden>
|
|
159
|
-
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
188
|
+
<svg class="word-wrap-icon-off" viewBox="0 0 24 24" aria-hidden="true">
|
|
189
|
+
<path d="M4 6h13a3 3 0 0 1 0 6H9"></path>
|
|
190
|
+
<path d="M12 9l-3 3 3 3"></path>
|
|
191
|
+
<path d="M4 18h8"></path>
|
|
192
|
+
<path d="M5 4l14 16"></path>
|
|
193
|
+
</svg>
|
|
194
|
+
<svg class="word-wrap-icon-on" viewBox="0 0 24 24" aria-hidden="true">
|
|
160
195
|
<path d="M4 6h13a3 3 0 0 1 0 6H9"></path>
|
|
161
196
|
<path d="M12 9l-3 3 3 3"></path>
|
|
162
197
|
<path d="M4 18h8"></path>
|
|
@@ -168,6 +203,7 @@
|
|
|
168
203
|
<path d="M20 5v6h-6"></path>
|
|
169
204
|
</svg>
|
|
170
205
|
</button>
|
|
206
|
+
</div>
|
|
171
207
|
</div>
|
|
172
208
|
<div class="change-hint">F7 / Shift+F7 · Cmd/Ctrl+Shift+Up/Down to jump.</div>
|
|
173
209
|
</div>
|
|
@@ -177,14 +213,14 @@
|
|
|
177
213
|
<div id="history-left-time" class="history-time"></div>
|
|
178
214
|
</div>
|
|
179
215
|
<div class="history-nav">
|
|
180
|
-
<button id="history-back" class="history-button icon-button" type="button" title="Open older commit" aria-label="Older commit">
|
|
216
|
+
<button id="history-back" class="history-button icon-button" type="button" title="Open older commit" data-tooltip="Open older commit" aria-label="Older commit">
|
|
181
217
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
182
218
|
<path d="M15 18l-6-6 6-6"></path>
|
|
183
219
|
<path d="M10 18l-6-6 6-6" opacity="0.7"></path>
|
|
184
220
|
</svg>
|
|
185
221
|
</button>
|
|
186
222
|
<div id="history-position" class="history-position" role="status" aria-live="polite" aria-atomic="true"></div>
|
|
187
|
-
<button id="history-forward" class="history-button icon-button" type="button" title="Open newer commit" aria-label="Newer commit">
|
|
223
|
+
<button id="history-forward" class="history-button icon-button" type="button" title="Open newer commit" data-tooltip="Open newer commit" aria-label="Newer commit">
|
|
188
224
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
189
225
|
<path d="M9 18l6-6-6-6"></path>
|
|
190
226
|
<path d="M14 18l6-6-6-6" opacity="0.7"></path>
|