-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.html
More file actions
198 lines (179 loc) · 6.84 KB
/
Copy pathindex.html
File metadata and controls
198 lines (179 loc) · 6.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
<!doctype html>
<html lang="en" data-theme="dark" style="color-scheme: dark">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="./clipper/clipper-logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#010409" />
<meta name="description" content="Open Clipper – AI-powered video clipping and editing tool by GrepCut" />
<title>Open Clipper</title>
<!-- Tło zgodne z backgroundColor okna Tauri — zapobiega jasnemu flashowi
zanim załaduje się CSS aplikacji. -->
<style>
html,
body,
#root {
background: #010409;
margin: 0;
height: 100%;
}
#open-clipper-boot-shell {
position: fixed;
inset: 0;
z-index: 2147483647;
display: flex;
align-items: center;
justify-content: center;
background: #010409;
color: #f8fafc;
font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
#open-clipper-boot-shell > div {
display: flex;
flex-direction: column;
align-items: center;
gap: 0;
}
#open-clipper-boot-shell > div > div:first-child {
display: flex;
align-items: center;
gap: 14px;
font-size: 18px;
font-weight: 600;
letter-spacing: -0.01em;
}
#open-clipper-boot-shell img,
#open-clipper-boot-shell .boot-logo {
width: 34px;
height: 34px;
object-fit: contain;
flex-shrink: 0;
}
#open-clipper-boot-shell .boot-fallback {
display: none;
margin-top: 18px;
max-width: 360px;
text-align: center;
font-size: 14px;
font-weight: 500;
line-height: 1.45;
color: #94a3b8;
}
#open-clipper-boot-shell.boot-stalled .boot-fallback {
display: block;
}
</style>
</head>
<body>
<div id="open-clipper-boot-shell" role="status" aria-label="Open Clipper is starting">
<div>
<div>
<img class="boot-logo" src="./clipper/clipper-logo.png" alt="" width="34" height="34" />
<span>Open Clipper</span>
</div>
<p class="boot-fallback">
Startup is taking longer than expected. Close and reopen Open Clipper if this screen does not disappear.
</p>
</div>
</div>
<div id="root"></div>
<!--
Inline bootstrap — replaces the former src/bootstrap.ts module.
Runs synchronously before the React bundle so we can:
1. Set up the Tauri startup-log bridge (__OPEN_CLIPPER_STARTUP_LOG__)
2. Provide __OPEN_CLIPPER_MARK_INTERACTIVE__ to dismiss the boot shell
3. Forward uncaught errors / unhandled rejections to the Tauri backend
4. Emit a 1-second heartbeat proving the event loop is alive
-->
<script>
(function () {
"use strict";
function stringify(value) {
if (value instanceof Error) {
return (value.name + ": " + value.message + "\n" + (value.stack || "")).trim();
}
if (typeof value === "string") return value;
try { return JSON.stringify(value); } catch (_) { return String(value); }
}
function report(level, message, details) {
var invoke = window.__TAURI__ && window.__TAURI__.core && window.__TAURI__.core.invoke;
if (!invoke) return;
invoke("frontend_startup_log", {
level: level,
message: message,
details: details === undefined ? null : stringify(details).slice(0, 20000),
}).catch(function () {});
}
// Expose the log bridge so main.tsx can call startupLog?.()
window.__OPEN_CLIPPER_STARTUP_LOG__ = report;
// Dismiss the boot shell when the first interactive route commits
var interactiveReported = false;
window.__OPEN_CLIPPER_MARK_INTERACTIVE__ = function (route) {
if (interactiveReported) return;
interactiveReported = true;
var shell = document.getElementById("open-clipper-boot-shell");
if (shell) shell.remove();
report("info", "interactive route committed", {
route: route,
navigationMs: Math.round(performance.now()),
});
};
// Forward console.error / console.warn to Tauri logs
var origError = console.error.bind(console);
var origWarn = console.warn.bind(console);
console.error = function () {
origError.apply(console, arguments);
report("error", "console.error", Array.prototype.map.call(arguments, stringify).join(" | "));
};
console.warn = function () {
origWarn.apply(console, arguments);
report("warn", "console.warn", Array.prototype.map.call(arguments, stringify).join(" | "));
};
// Catch-all error handlers
window.addEventListener("error", function (event) {
report("error", "uncaught window error", {
message: event.message,
filename: event.filename,
line: event.lineno,
column: event.colno,
error: stringify(event.error),
});
});
window.addEventListener("unhandledrejection", function (event) {
report("error", "unhandled promise rejection", event.reason);
});
report("info", "frontend bootstrap started", window.location.href);
// Heartbeat — proof the event loop is alive
window.setTimeout(function () {
report("info", "frontend event loop heartbeat after 1 second");
}, 1000);
window.setTimeout(function () {
if (interactiveReported) return;
var shell = document.getElementById("open-clipper-boot-shell");
if (shell) shell.classList.add("boot-stalled");
report("warn", "boot shell still visible after startup timeout", {
navigationMs: Math.round(performance.now()),
});
}, 20000);
// Observe #root so we can report when React commits its first content
var root = document.getElementById("root");
if (root) {
var observer = new MutationObserver(function () {
if (root.childNodes.length > 0) {
report("info", "React committed its first DOM content", {
childNodes: root.childNodes.length,
textPreview: (root.textContent || "").slice(0, 200),
navigationMs: Math.round(performance.now()),
});
observer.disconnect();
}
});
observer.observe(root, { childList: true, subtree: true });
} else {
report("error", "root DOM element is missing before frontend import");
}
})();
</script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>