termsearch 0.3.8 → 0.3.10
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/frontend/dist/app.js +15 -10
- package/frontend/dist/style.css +72 -7
- package/package.json +1 -1
- package/src/api/routes.js +17 -0
- package/src/autostart/manager.js +4 -2
- package/frontend/dist/opensearch.xml +0 -8
package/frontend/dist/app.js
CHANGED
|
@@ -1148,20 +1148,25 @@ function addToBrowser() {
|
|
|
1148
1148
|
// Show inline hint
|
|
1149
1149
|
const existing = document.querySelector('.add-browser-hint');
|
|
1150
1150
|
if (existing) { existing.remove(); return; }
|
|
1151
|
+
const searchUrl = `${location.origin}/#/?q=%s`;
|
|
1152
|
+
const urlBox = el('div', { className: 'add-browser-url' });
|
|
1153
|
+
const urlText = el('code', {}, searchUrl);
|
|
1154
|
+
const copyBtn = el('button', { className: 'add-browser-copy', type: 'button', onClick: () => {
|
|
1155
|
+
navigator.clipboard.writeText(searchUrl).then(() => { copyBtn.textContent = 'Copied!'; setTimeout(() => { copyBtn.textContent = 'Copy'; }, 2000); }).catch(() => {});
|
|
1156
|
+
} }, 'Copy');
|
|
1157
|
+
urlBox.append(urlText, copyBtn);
|
|
1151
1158
|
const hint = el('div', { className: 'add-browser-hint' },
|
|
1152
|
-
el('
|
|
1153
|
-
el('div', {
|
|
1154
|
-
el('span', {
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
el('span', { style: 'color:var(--text2)' }, 'Chrome'), ' — Settings → Search engine → Manage → Add',
|
|
1158
|
-
),
|
|
1159
|
-
el('div', { style: 'margin-top:3px;font-family:var(--font-mono);font-size:10px;color:var(--text3);word-break:break-all' },
|
|
1160
|
-
`URL: ${location.origin}/#/?q=%s`,
|
|
1159
|
+
el('div', { className: 'add-browser-title' }, 'Add TermSearch to your browser'),
|
|
1160
|
+
el('div', { className: 'add-browser-steps' },
|
|
1161
|
+
el('div', {}, el('span', { className: 'add-browser-badge' }, 'Firefox'), ' Address bar → click TermSearch icon → "Add"'),
|
|
1162
|
+
el('div', {}, el('span', { className: 'add-browser-badge' }, 'Chrome'), ' Settings → Search engine → Manage → Add'),
|
|
1163
|
+
el('div', {}, el('span', { className: 'add-browser-badge' }, 'Safari'), ' Not natively supported — use extension or bookmark'),
|
|
1161
1164
|
),
|
|
1165
|
+
el('div', { className: 'add-browser-label' }, 'Search URL (paste in browser settings):'),
|
|
1166
|
+
urlBox,
|
|
1162
1167
|
);
|
|
1163
1168
|
document.querySelector('.home-actions')?.after(hint);
|
|
1164
|
-
setTimeout(() => hint.remove(),
|
|
1169
|
+
setTimeout(() => hint.remove(), 20000);
|
|
1165
1170
|
}
|
|
1166
1171
|
|
|
1167
1172
|
function renderHome(app) {
|
package/frontend/dist/style.css
CHANGED
|
@@ -937,16 +937,81 @@ a:hover { color: var(--link-h); }
|
|
|
937
937
|
|
|
938
938
|
/* ─── Add to browser hint ─────────────────────────────────────────────────── */
|
|
939
939
|
.add-browser-hint {
|
|
940
|
-
max-width:
|
|
941
|
-
margin:
|
|
942
|
-
padding:
|
|
940
|
+
max-width: 420px;
|
|
941
|
+
margin: 20px auto 0;
|
|
942
|
+
padding: 16px 20px;
|
|
943
943
|
border-radius: var(--radius);
|
|
944
|
-
background: rgba(30,27,75,0.
|
|
945
|
-
border: 1px solid rgba(109,40,217,0.
|
|
944
|
+
background: rgba(30,27,75,0.45);
|
|
945
|
+
border: 1px solid rgba(109,40,217,0.35);
|
|
946
|
+
color: var(--text2);
|
|
947
|
+
font-size: 12px;
|
|
948
|
+
line-height: 1.7;
|
|
949
|
+
animation: fadeIn 0.2s ease;
|
|
950
|
+
}
|
|
951
|
+
.add-browser-title {
|
|
952
|
+
font-size: 13px;
|
|
953
|
+
font-weight: 700;
|
|
954
|
+
color: var(--text);
|
|
955
|
+
margin-bottom: 10px;
|
|
956
|
+
}
|
|
957
|
+
.add-browser-steps {
|
|
958
|
+
display: flex;
|
|
959
|
+
flex-direction: column;
|
|
960
|
+
gap: 5px;
|
|
961
|
+
margin-bottom: 12px;
|
|
962
|
+
}
|
|
963
|
+
.add-browser-badge {
|
|
964
|
+
display: inline-block;
|
|
965
|
+
padding: 1px 7px;
|
|
966
|
+
border-radius: 99px;
|
|
967
|
+
font-size: 10px;
|
|
968
|
+
font-weight: 700;
|
|
969
|
+
background: rgba(167,139,250,0.18);
|
|
970
|
+
color: #a78bfa;
|
|
971
|
+
border: 1px solid rgba(167,139,250,0.3);
|
|
972
|
+
letter-spacing: 0.02em;
|
|
973
|
+
}
|
|
974
|
+
.add-browser-label {
|
|
975
|
+
font-size: 10px;
|
|
946
976
|
color: var(--text3);
|
|
977
|
+
text-transform: uppercase;
|
|
978
|
+
letter-spacing: 0.04em;
|
|
979
|
+
margin-bottom: 6px;
|
|
980
|
+
}
|
|
981
|
+
.add-browser-url {
|
|
982
|
+
display: flex;
|
|
983
|
+
align-items: center;
|
|
984
|
+
gap: 8px;
|
|
985
|
+
padding: 8px 12px;
|
|
986
|
+
border-radius: var(--radius-sm);
|
|
987
|
+
background: rgba(0,0,0,0.4);
|
|
988
|
+
border: 1px solid rgba(167,139,250,0.25);
|
|
989
|
+
}
|
|
990
|
+
.add-browser-url code {
|
|
991
|
+
flex: 1;
|
|
992
|
+
min-width: 0;
|
|
993
|
+
font-family: var(--font-mono);
|
|
994
|
+
font-size: 12px;
|
|
995
|
+
font-weight: 600;
|
|
996
|
+
color: #c4b5fd;
|
|
997
|
+
word-break: break-all;
|
|
998
|
+
user-select: all;
|
|
999
|
+
}
|
|
1000
|
+
.add-browser-copy {
|
|
1001
|
+
flex-shrink: 0;
|
|
1002
|
+
padding: 4px 12px;
|
|
1003
|
+
border-radius: var(--radius-sm);
|
|
1004
|
+
border: 1px solid rgba(167,139,250,0.35);
|
|
1005
|
+
background: rgba(109,40,217,0.25);
|
|
1006
|
+
color: #e0d4fd;
|
|
947
1007
|
font-size: 11px;
|
|
948
|
-
|
|
949
|
-
|
|
1008
|
+
font-weight: 600;
|
|
1009
|
+
cursor: pointer;
|
|
1010
|
+
transition: background 0.15s, border-color 0.15s;
|
|
1011
|
+
}
|
|
1012
|
+
.add-browser-copy:hover {
|
|
1013
|
+
background: rgba(109,40,217,0.45);
|
|
1014
|
+
border-color: rgba(167,139,250,0.55);
|
|
950
1015
|
}
|
|
951
1016
|
|
|
952
1017
|
/* ─── Footer ──────────────────────────────────────────────────────────────── */
|
package/package.json
CHANGED
package/src/api/routes.js
CHANGED
|
@@ -231,6 +231,23 @@ export function createRouter(config, rateLimiters) {
|
|
|
231
231
|
});
|
|
232
232
|
});
|
|
233
233
|
|
|
234
|
+
// ─── OpenSearch (dynamic — adapts to host/port) ─────────────────────────
|
|
235
|
+
router.get('/opensearch.xml', (req, res) => {
|
|
236
|
+
const proto = req.protocol;
|
|
237
|
+
const host = req.get('host') || `${req.hostname}:${req.socket.localPort}`;
|
|
238
|
+
const origin = `${proto}://${host}`;
|
|
239
|
+
res.setHeader('Content-Type', 'application/opensearchdescription+xml; charset=utf-8');
|
|
240
|
+
res.setHeader('Cache-Control', 'public, max-age=3600');
|
|
241
|
+
res.send(`<?xml version="1.0" encoding="UTF-8"?>
|
|
242
|
+
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
|
|
243
|
+
<ShortName>TermSearch</ShortName>
|
|
244
|
+
<Description>TermSearch — personal search engine</Description>
|
|
245
|
+
<InputEncoding>UTF-8</InputEncoding>
|
|
246
|
+
<Image height="64" width="64" type="image/svg+xml">${origin}/icon.svg</Image>
|
|
247
|
+
<Url type="text/html" method="get" template="${origin}/#/?q={searchTerms}"/>
|
|
248
|
+
</OpenSearchDescription>`);
|
|
249
|
+
});
|
|
250
|
+
|
|
234
251
|
// ─── OpenAPI ─────────────────────────────────────────────────────────────
|
|
235
252
|
router.get('/api/openapi.json', (_req, res) => {
|
|
236
253
|
applySecurityHeaders(res);
|
package/src/autostart/manager.js
CHANGED
|
@@ -50,7 +50,7 @@ function termuxStatus() {
|
|
|
50
50
|
function termuxEnable() {
|
|
51
51
|
fs.mkdirSync(TERMUX_BOOT_DIR, { recursive: true });
|
|
52
52
|
const bin = findBin();
|
|
53
|
-
const sh = `#!/data/data/com.termux/files/usr/bin/sh\n# TermSearch autostart\n${bin} &\n`;
|
|
53
|
+
const sh = `#!/data/data/com.termux/files/usr/bin/sh\n# TermSearch autostart\n${bin} start --fg &\n`;
|
|
54
54
|
fs.writeFileSync(TERMUX_BOOT_FILE, sh, { mode: 0o755 });
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -103,7 +103,7 @@ function linuxEnable() {
|
|
|
103
103
|
'',
|
|
104
104
|
'[Service]',
|
|
105
105
|
'Type=simple',
|
|
106
|
-
`ExecStart=${bin}`,
|
|
106
|
+
`ExecStart=${bin} start --fg`,
|
|
107
107
|
'Restart=on-failure',
|
|
108
108
|
'RestartSec=5',
|
|
109
109
|
'',
|
|
@@ -156,6 +156,8 @@ function macosEnable() {
|
|
|
156
156
|
<key>ProgramArguments</key>
|
|
157
157
|
<array>
|
|
158
158
|
<string>${bin}</string>
|
|
159
|
+
<string>start</string>
|
|
160
|
+
<string>--fg</string>
|
|
159
161
|
</array>
|
|
160
162
|
<key>RunAtLoad</key>
|
|
161
163
|
<true/>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
|
|
3
|
-
<ShortName>TermSearch</ShortName>
|
|
4
|
-
<Description>TermSearch — personal search engine</Description>
|
|
5
|
-
<InputEncoding>UTF-8</InputEncoding>
|
|
6
|
-
<Image height="64" width="64" type="image/svg+xml">/icon.svg</Image>
|
|
7
|
-
<Url type="text/html" method="get" template="http://localhost:3000/#/?q={searchTerms}"/>
|
|
8
|
-
</OpenSearchDescription>
|