4 Commits

Author SHA1 Message Date
d873d99b23 ssb: Handful of URL encoding issues.
All checks were successful
Build Tilde Friends / Build-Docs (push) Successful in 2m25s
Build Tilde Friends / Build-All (push) Successful in 10m9s
2025-12-15 20:42:57 -05:00
1a5392d942 ssb: Avoid an unnecessary messages load.
All checks were successful
Build Tilde Friends / Build-Docs (push) Successful in 2m30s
Build Tilde Friends / Build-All (push) Successful in 10m54s
2025-12-15 12:30:27 -05:00
ef80c0910c intro: Scroll to top when switching pages.
All checks were successful
Build Tilde Friends / Build-Docs (push) Successful in 2m34s
Build Tilde Friends / Build-All (push) Successful in 15m36s
2025-12-13 09:01:17 -05:00
6c641acdd3 ssb: Put the hamburger menu on the same line as the welcome text. 2025-12-13 08:57:06 -05:00
8 changed files with 73 additions and 54 deletions

View File

@@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "💡", "emoji": "💡",
"previous": "&eN6DNPpQUNhGvxneLuLPgsOXR6qyFZ7u+MAz0b4fa7k=.sha256" "previous": "&FGkkfFLaEID3V4lUjPbgCOwgEvNXkcVkzs0zzwD/gQ8=.sha256"
} }

View File

@@ -34,6 +34,7 @@
class="w3-flex w3-dark-gray w3-center" class="w3-flex w3-dark-gray w3-center"
> >
<div <div
id="scrollbox"
style=" style="
flex: 1 1 auto; flex: 1 1 auto;
overflow: auto; overflow: auto;
@@ -251,6 +252,7 @@
index == 0 ? 'hidden' : 'visible'; index == 0 ? 'hidden' : 'visible';
document.getElementById('right').style.visibility = document.getElementById('right').style.visibility =
index == slides.length - 1 ? 'hidden' : 'visible'; index == slides.length - 1 ? 'hidden' : 'visible';
document.getElementById('scrollbox').scrollTo(0, 0);
} }
let dots = [...document.getElementsByClassName('dot')]; let dots = [...document.getElementsByClassName('dot')];

View File

@@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🦀", "emoji": "🦀",
"previous": "&/flKW9HptO5lHG19rMwc4GT9rGBFiRqVD87VDbWvsgc=.sha256" "previous": "&KPnjURiuJa5b0ONjxz11bMm7yuhY9wlBTyB+fzl0zzk=.sha256"
} }

View File

@@ -707,9 +707,7 @@ class TfElement extends LitElement {
.following=${this.following} .following=${this.following}
whoami=${this.whoami} whoami=${this.whoami}
.users=${this.users} .users=${this.users}
query=${this.hash?.startsWith('#q=') query=${this.search_text()}
? decodeURIComponent(this.hash.substring(3))
: null}
></tf-tab-search> ></tf-tab-search>
`; `;
} }
@@ -758,7 +756,7 @@ class TfElement extends LitElement {
search_text.focus(); search_text.focus();
this.set_tab('search'); this.set_tab('search');
} else { } else {
this.set_hash('#q=' + search_text.value); this.set_hash('#q=' + encodeURIComponent(search_text.value));
} }
} }
@@ -768,6 +766,16 @@ class TfElement extends LitElement {
} }
} }
search_text() {
if (this.hash.startsWith('#q=')) {
try {
return decodeURIComponent(this.hash.substring('#q='.length));
} catch {
return this.hash.substring('#q='.length);
}
}
}
render() { render() {
let self = this; let self = this;
@@ -832,7 +840,7 @@ class TfElement extends LitElement {
: undefined : undefined
} }
<button class="w3-bar-item w3-button w3-right" @click=${this.search}>🔍<span class="w3-hide-small">Search</span></button> <button class="w3-bar-item w3-button w3-right" @click=${this.search}>🔍<span class="w3-hide-small">Search</span></button>
<input type="text" class=${'w3-input w3-bar-item w3-right w3-theme-d1' + (this.tab == 'search' ? ' w3-mobile' : ' w3-hide-small')} placeholder="keywords, @id, #channel" id="search_text" @keydown=${this.search_keydown}></input> <input type="text" class=${'w3-input w3-bar-item w3-right w3-theme-d1' + (this.tab == 'search' ? ' w3-mobile' : ' w3-hide-small')} placeholder="keywords, @id, #channel" id="search_text" @keydown=${this.search_keydown} value=${this.search_text()}></input>
</div> </div>
`; `;
let contents = this.guest let contents = this.guest

View File

@@ -398,12 +398,19 @@ class TfTabNewsFeedElement extends LitElement {
); );
} }
make_messages_key() {
return JSON.stringify([
this.hash,
Object.keys(this.channels_latest ?? {}).filter((x) => x != '🔐'),
]);
}
async load_messages() { async load_messages() {
let start_time = new Date(); let start_time = new Date();
let self = this; let self = this;
this.loading++; this.loading++;
let messages = []; let messages = [];
let original_key = JSON.stringify([this.hash, this.channels_latest ?? {}]); let original_key = this.make_messages_key();
try { try {
if (this._messages_key !== original_key) { if (this._messages_key !== original_key) {
this.messages = []; this.messages = [];
@@ -429,7 +436,7 @@ class TfTabNewsFeedElement extends LitElement {
} finally { } finally {
this.loading--; this.loading--;
} }
let current_key = JSON.stringify([this.hash, this.channels_latest ?? {}]); let current_key = this.make_messages_key();
if (current_key === original_key) { if (current_key === original_key) {
this.messages = this.merge_messages(this.messages, messages); this.messages = this.merge_messages(this.messages, messages);
} }
@@ -486,19 +493,18 @@ class TfTabNewsFeedElement extends LitElement {
render() { render() {
if ( if (
!this.messages || !this.messages ||
this._messages_key !== this._messages_key !== this.make_messages_key() ||
JSON.stringify([this.hash, this.channels_latest ?? {}]) ||
this._messages_following !== JSON.stringify(this.following) || this._messages_following !== JSON.stringify(this.following) ||
this._private_messages !== (this.hash.startsWith('#🔐') &&
JSON.stringify([ this._private_messages !==
this.private_messages, JSON.stringify([
this.grouped_private_messages, this.private_messages,
]) || this.grouped_private_messages,
this._channels_latest !== ]))
JSON.stringify(Object.keys(this.channels_latest))
) { ) {
console.log(this._messages_key, this.make_messages_key());
console.log( console.log(
`loading messages for ${this.whoami} (messages=${!this.messages},${this._messages_hash != this.hash} following=${this._messages_following !== JSON.stringify(this.following)}, channels=${this._channels_latest !== JSON.stringify(Object.keys(this.channels_latest))}, private=${this._private_messages !== JSON.stringify([this.private_messages, this.grouped_private_messages])},${this.private_messages?.length},${Object.keys(this.grouped_private_messages ?? {}).length})` `loading messages for ${this.whoami} (messages=${!this.messages},${this._messages_key != this.make_messages_key()} following=${this._messages_following !== JSON.stringify(this.following)}, private=${this._private_messages !== JSON.stringify([this.private_messages, this.grouped_private_messages])},${this.private_messages?.length},${Object.keys(this.grouped_private_messages ?? {}).length})`
); );
this.load_messages(); this.load_messages();
} }

View File

@@ -428,18 +428,18 @@ class TfTabNewsElement extends LitElement {
</p> </p>
<div> <div>
<div <div
id="show_sidebar" style="width: 100%; max-width: 100%; white-space: nowrap; overflow: hidden"
class="w3-button w3-hide-large"
@click=${this.show_sidebar}
>
${this.unread_status()}&#9776;
</div>
<span
style="display: inline-block; width: 100%; max-width: 100%; white-space: nowrap; overflow: hidden"
> >
<button
id="show_sidebar"
class="w3-button w3-hide-large"
@click=${this.show_sidebar}
>
${this.unread_status()}&#9776;
</button>
Welcome, Welcome,
<tf-user id=${this.whoami} .users=${this.users}></tf-user>! <tf-user id=${this.whoami} .users=${this.users}></tf-user>!
</span> </div>
${edit_profile} ${edit_profile}
</div> </div>
<div> <div>

View File

@@ -44,36 +44,37 @@ class TfTabSearchElement extends LitElement {
this.error = undefined; this.error = undefined;
this.results = []; this.results = [];
this.messages = []; this.messages = [];
if (query.startsWith('sql:')) { try {
this.messages = []; if (query.startsWith('sql:')) {
try { this.messages = [];
this.results = await tfrpc.rpc.query( this.results = await tfrpc.rpc.query(
query.substring('sql:'.length), query.substring('sql:'.length),
[] []
); );
} catch (e) { } else {
this.results = []; let results = await tfrpc.rpc.query(
this.error = e; `
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
FROM messages_fts(?)
JOIN messages ON messages.rowid = messages_fts.rowid
JOIN json_each(?) AS following ON messages.author = following.value
ORDER BY timestamp DESC limit 100
`,
['"' + query.replace('"', '""') + '"', JSON.stringify(this.following)]
);
search = this.renderRoot.getElementById('search');
if (search) {
search.value = query;
search.focus();
search.select();
}
this.messages = results;
} }
} else { } catch (e) {
let results = await tfrpc.rpc.query( this.messages = [];
` this.results = [];
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature this.error = e;
FROM messages_fts(?) console.log(e);
JOIN messages ON messages.rowid = messages_fts.rowid
JOIN json_each(?) AS following ON messages.author = following.value
ORDER BY timestamp DESC limit 100
`,
['"' + query.replace('"', '""') + '"', JSON.stringify(this.following)]
);
console.log('Done.');
search = this.renderRoot.getElementById('search');
if (search) {
search.value = query;
search.focus();
search.select();
}
this.messages = results;
} }
} }

View File

@@ -39,7 +39,9 @@ class TfUserElement extends LitElement {
name = this.icon_only name = this.icon_only
? undefined ? undefined
: !this.nolink : !this.nolink
? html`<a target="_top" href=${'#' + this.id}>${name_string}</a>` ? html`<a target="_top" href=${'#' + encodeURIComponent(this.id)}
>${name_string}</a
>`
: html`<span>${name_string}</span>`; : html`<span>${name_string}</span>`;
if (user) { if (user) {