10 Commits

Author SHA1 Message Date
4040d6aa08 ssb: Hide 'Mark as read' when we're not in a channel with a read status. #122
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 32m52s
2025-05-31 15:23:07 -04:00
1c96f5c35e ssb: Slight tweaks to 'This message is not currently available.' 2025-05-31 15:20:55 -04:00
4d3e42812d ssb: Condense follows/blocks more, and support replies to them. #122 2025-05-31 15:17:07 -04:00
f7b3711d4f ssb: Bury placeholder message blob ids in a context menu. #122
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 34m4s
2025-05-31 11:44:50 -04:00
2408e076ff ssb: Indicate connection status with some colors in the connections list in the sidebar. #122
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-05-31 11:28:09 -04:00
6f71ffb477 ssb: Treat most plaintext votes as 👍. #122
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 33m12s
2025-05-31 10:52:07 -04:00
214433f36a update: CodeMirror.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 32m41s
2025-05-29 12:39:31 -04:00
309b22732e update: sqlite 3.50.0.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-05-29 12:37:14 -04:00
6fe7687b2a docs: Update the screenshots.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 32m44s
2025-05-28 20:49:48 -04:00
a8cbf757ff build: Let's start work on 0.0.32. nix => 0.0.31.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 32m47s
2025-05-28 18:12:15 -04:00
22 changed files with 3719 additions and 1901 deletions

View File

@@ -16,14 +16,14 @@ MAKEFLAGS += --no-builtin-rules
## LD := Linker.
## ANDROID_SDK := Path to the Android SDK.
VERSION_CODE := 37
VERSION_CODE_IOS := 13
VERSION_NUMBER := 0.0.31
VERSION_CODE := 38
VERSION_CODE_IOS := 14
VERSION_NUMBER := 0.0.32-wip
VERSION_NAME := This program kills fascists.
IPHONEOS_VERSION_MIN=14.0
SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3490200.zip
SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3500000.zip
BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar
APPIMAGETOOL_URL := https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
APPIMAGETOOL_MD5 := e989fadfc4d685fd3d6aeeb9b525d74d out/appimagetool

View File

@@ -1,5 +1,5 @@
{
"type": "tildefriends-app",
"emoji": "🦀",
"previous": "&0Lxm4IgS3mpvSccP3bg7wNPACtLKMTbie51ea/vJbeg=.sha256"
"previous": "&DJCofULiC7mj62IoWQGTveRUQvFrf9oL5BBaUhXQdf0=.sha256"
}

View File

@@ -86,12 +86,16 @@ class TfMessageElement extends LitElement {
render_votes() {
function normalize_expression(expression) {
if (expression === 'Like' || expression === 'like' || !expression) {
return '👍';
} else if (expression === 'Unlike' || expression === 'unlike') {
if (
expression === 'Unlike' ||
expression === 'unlike' ||
expression == 'undig'
) {
return '👎';
} else if (expression === 'heart') {
return '❤️';
} else if (expression.split('').every((x) => x.charCodeAt(0) < 256)) {
return '👍';
} else {
return expression;
}
@@ -297,31 +301,35 @@ class TfMessageElement extends LitElement {
return total;
}
expanded_key() {
return this.message?.id || this.messages?.map((x) => x.id).join(':');
}
set_expanded(expanded, tag) {
let key = this.expanded_key();
this.dispatchEvent(
new CustomEvent('tf-expand', {
bubbles: true,
composed: true,
detail: {id: (this.message.id || '') + (tag || ''), expanded: expanded},
detail: {id: key + (tag || ''), expanded: expanded},
})
);
}
toggle_expanded(tag) {
this.set_expanded(
!this.expanded[(this.message.id || '') + (tag || '')],
tag
);
let key = this.expanded_key();
this.set_expanded(!this.expanded[key + (tag || '')], tag);
}
is_expanded(tag) {
return this.expanded[(this.message.id || '') + (tag || '')];
let key = this.expanded_key();
return this.expanded[key + (tag || '')];
}
render_children() {
let self = this;
if (this.message.child_messages?.length) {
if (!this.expanded[this.message.id]) {
if (!this.expanded[this.expanded_key()]) {
return html`
<button
class="w3-button w3-theme-d1 w3-block w3-bar"
@@ -574,6 +582,44 @@ class TfMessageElement extends LitElement {
`;
}
content_group_by_author() {
let sorted = this.message.messages
.map((x) => [
x.author,
x.content.blocking !== undefined
? x.content.blocking
? 'is blocking'
: 'is no longer blocking'
: x.content.following !== undefined
? x.content.following
? 'is following'
: 'is no longer following'
: '',
x.content.contact,
x,
])
.sort();
let result = [];
let last;
let group;
for (let row of sorted) {
if (last && last[0] == row[0] && last[1] == row[1]) {
group.push(row[2]);
} else {
if (group) {
result.push({author: last[0], action: last[1], users: group});
}
last = row;
group = [row[2]];
}
}
if (group) {
result.push({author: last[0], action: last[1], users: group});
}
console.log(this.message.messages, result);
return result;
}
render() {
let content = this.message?.content;
if (this.message?.decrypted?.type == 'post') {
@@ -582,29 +628,88 @@ class TfMessageElement extends LitElement {
let class_background = this.class_background();
let self = this;
if (this.message?.type === 'contact_group') {
return this.render_frame(
html` ${this.message.messages.map(
(x) =>
html`<tf-message
.message=${x}
whoami=${this.whoami}
.users=${this.users}
.drafts=${this.drafts}
.expanded=${this.expanded}
channel=${this.channel}
channel_unread=${this.channel_unread}
></tf-message>`
)}`
);
if (this.expanded[this.expanded_key()]) {
return this.render_frame(html`
<div class="w3-padding">
${this.message.messages.map(
(x) =>
html`<tf-message
.message=${x}
whoami=${this.whoami}
.users=${this.users}
.drafts=${this.drafts}
.expanded=${this.expanded}
channel=${this.channel}
channel_unread=${this.channel_unread}
></tf-message>`
)}
</div>
<button
class="w3-button w3-theme-d1 w3-block w3-bar"
style="box-sizing: border-box"
@click=${() => self.set_expanded(false)}
>
Collapse
</button>
`);
} else {
return this.render_frame(html`
<div class="w3-padding">
${this.content_group_by_author().map(
(x) => html`
<tf-user id=${x.author} .users=${this.users}></tf-user>
${x.action}
${x.users.map(
(y) => html`
<tf-user id=${y} .users=${this.users}></tf-user>
`
)}
`
)}
</div>
<button
class="w3-button w3-theme-d1 w3-block w3-bar"
style="box-sizing: border-box"
@click=${() => self.set_expanded(true)}
>
Expand
</button>
`);
}
} else if (this.message.placeholder) {
return this.render_frame(
html`<div class="w3-padding">
<p>
<a target="_top" href=${'#' + encodeURIComponent(this.message.id)}
>${this.message.id}</a
html`<div>
<div class="w3-bar">
<a
class="w3-bar-item w3-panel w3-round-xlarge w3-theme-d1 w3-margin w3-button"
target="_top"
href=${'#' + encodeURIComponent(this.message?.id)}
>
(placeholder)
</p>
This message is not currently available.
</a>
<div class="w3-bar-item w3-right">
<button class="w3-button w3-theme-d1" @click=${this.toggle_menu}>
%
</button>
<div
class="w3-dropdown-content w3-bar-block w3-card-4 w3-theme-l1"
style="right: 48px"
>
<a
target="_top"
class="w3-button w3-bar-item"
href=${'#' + encodeURIComponent(this.message?.id)}
>View Message</a
>
<button
class="w3-button w3-bar-item w3-border-bottom"
@click=${this.copy_id}
>
Copy ID
</button>
</div>
</div>
</div>
<div>${this.render_votes()}</div>
${(this.message.child_messages || []).map(
(x) => html`
@@ -654,25 +759,60 @@ class TfMessageElement extends LitElement {
</div>
`);
} else if (content.type == 'contact') {
return html`
<div class="w3-padding">
<tf-user id=${this.message.author} .users=${this.users}></tf-user>
is
${content.blocking === true
? 'blocking'
: content.blocking === false
? 'no longer blocking'
: content.following === true
? 'following'
: content.following === false
? 'no longer following'
: '?'}
<tf-user
id=${this.message.content.contact}
.users=${this.users}
></tf-user>
return this.render_frame(html`
<div class="w3-bar">
<div class="w3-bar-item">
<tf-user id=${this.message.author} .users=${this.users}></tf-user>
is
${content.blocking === true
? 'blocking'
: content.blocking === false
? 'no longer blocking'
: content.following === true
? 'following'
: content.following === false
? 'no longer following'
: '?'}
<tf-user
id=${this.message.content.contact}
.users=${this.users}
></tf-user>
</div>
<div class="w3-bar-item w3-right">
<button class="w3-button w3-theme-d1" @click=${this.toggle_menu}>
%
</button>
<div
class="w3-dropdown-content w3-bar-block w3-card-4 w3-theme-l1"
style="right: 48px"
>
<a
target="_top"
class="w3-button w3-bar-item"
href=${'#' + encodeURIComponent(this.message?.id)}
>View Message</a
>
<button
class="w3-button w3-bar-item w3-border-bottom"
@click=${this.copy_id}
>
Copy ID
</button>
${this.drafts[this.message?.id] === undefined
? html`
<button
class="w3-button w3-bar-item"
@click=${this.show_reply}
>
↩️ Reply
</button>
`
: undefined}
</div>
</div>
${this.render_votes()} ${this.render_actions()}
</div>
`;
`);
} else if (content.type == 'post') {
let self = this;
let body;

View File

@@ -166,7 +166,10 @@ class TfNewsElement extends LitElement {
if (message?.content?.type === 'contact') {
group.push(message);
} else {
if (group.length > 0) {
if (group.length == 1) {
result.push(group[0]);
group = [];
} else if (group.length > 1) {
result.push({
rowid: Math.max(...group.map((x) => x.rowid)),
type: 'contact_group',
@@ -177,7 +180,10 @@ class TfNewsElement extends LitElement {
result.push(message);
}
}
if (group.length > 0) {
if (group.length == 1) {
result.push(group[0]);
group = [];
} else if (group.length > 1) {
result.push({
rowid: Math.max(...group.map((x) => x.rowid)),
type: 'contact_group',

View File

@@ -441,9 +441,14 @@ class TfTabNewsFeedElement extends LitElement {
`;
}
return cache(html`
<button class="w3-button w3-theme-d1" @click=${this.mark_all_read}>
Mark All Read
</button>
${!this.hash.startsWith('#%')
? html`<button
class="w3-button w3-theme-d1"
@click=${this.mark_all_read}
>
Mark All Read
</button>`
: undefined}
<tf-news
id="news"
whoami=${this.whoami}

View File

@@ -235,12 +235,18 @@ class TfTabNewsElement extends LitElement {
<h4 style="margin: 0">Connections</h4>
</a>
${this.connections
.filter((x) => x.id && !x.destroy_reason)
.filter((x) => x.id)
.map(
(x) => html`
<tf-user
class="w3-bar-item"
style="max-width: 100%"
style=${x.destroy_reason
? 'border-left: 4px solid red; border-right: 4px solid red'
: x.connected
? x.flags?.one_shot
? 'border-left: 4px solid blue; border-right: 4px solid blue'
: 'border-left: 4px solid green; border-right: 4px solid green'
: ''}
id=${x.id}
fallback_name=${x.host}
.users=${this.users}

View File

@@ -25,14 +25,14 @@
}:
pkgs.stdenv.mkDerivation rec {
pname = "tildefriends";
version = "0.0.30";
version = "0.0.31";
src = pkgs.fetchFromGitea {
domain = "dev.tildefriends.net";
owner = "cory";
repo = "tildefriends";
rev = "v${version}";
hash = "sha256-t5yvouzSL2j/ge1VHLqzIZ+Avqj4iEDt7L+yrHoTZAQ=";
hash = "sha256-c2ZKVNikI5jN5GQuvp7S53qqnRZniSrJMF1FUZdVNPI=";
fetchSubmodules = true;
};

File diff suppressed because one or more lines are too long

View File

@@ -144,9 +144,9 @@
}
},
"node_modules/@codemirror/view": {
"version": "6.36.8",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.8.tgz",
"integrity": "sha512-yoRo4f+FdnD01fFt4XpfpMCcCAo9QvZOtbrXExn4SqzH32YC6LgzqxfLZw/r6Ge65xyY03mK/UfUqrVw1gFiFg==",
"version": "6.37.0",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.37.0.tgz",
"integrity": "sha512-ghHIeRGfWB8h9Tc3sMdr7D5zp4sZvlCzG36Xjdh2ymmfAwvSaCJAAsL3HLyLEnHcE953+5Uox1bx5OS+YCW/7Q==",
"dependencies": {
"@codemirror/state": "^6.5.0",
"style-mod": "^4.1.0",

953
deps/sqlite/shell.c vendored

File diff suppressed because it is too large Load Diff

4208
deps/sqlite/sqlite3.c vendored

File diff suppressed because it is too large Load Diff

146
deps/sqlite/sqlite3.h vendored
View File

@@ -133,7 +133,7 @@ extern "C" {
**
** Since [version 3.6.18] ([dateof:3.6.18]),
** SQLite source code has been stored in the
** <a href="http://www.fossil-scm.org/">Fossil configuration management
** <a href="http://fossil-scm.org/">Fossil configuration management
** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
** a string which identifies a particular check-in of SQLite
** within its configuration management system. ^The SQLITE_SOURCE_ID
@@ -146,9 +146,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.49.2"
#define SQLITE_VERSION_NUMBER 3049002
#define SQLITE_SOURCE_ID "2025-05-07 10:39:52 17144570b0d96ae63cd6f3edca39e27ebd74925252bbaf6723bcb2f6b4861fb1"
#define SQLITE_VERSION "3.50.0"
#define SQLITE_VERSION_NUMBER 3050000
#define SQLITE_SOURCE_ID "2025-05-29 14:26:00 dfc790f998f450d9c35e3ba1c8c89c17466cb559f87b0239e4aab9d34e28f742"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -1163,6 +1163,12 @@ struct sqlite3_io_methods {
** the value that M is to be set to. Before returning, the 32-bit signed
** integer is overwritten with the previous value of M.
**
** <li>[[SQLITE_FCNTL_BLOCK_ON_CONNECT]]
** The [SQLITE_FCNTL_BLOCK_ON_CONNECT] opcode is used to configure the
** VFS to block when taking a SHARED lock to connect to a wal mode database.
** This is used to implement the functionality associated with
** SQLITE_SETLK_BLOCK_ON_CONNECT.
**
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
** a database file. The argument is a pointer to a 32-bit unsigned integer.
@@ -1259,6 +1265,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_CKSM_FILE 41
#define SQLITE_FCNTL_RESET_CACHE 42
#define SQLITE_FCNTL_NULL_IO 43
#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1989,13 +1996,16 @@ struct sqlite3_mem_methods {
**
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
** the default size of lookaside memory on each [database connection].
** the default size of [lookaside memory] on each [database connection].
** The first argument is the
** size of each lookaside buffer slot and the second is the number of
** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE
** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
** option to [sqlite3_db_config()] can be used to change the lookaside
** configuration on individual connections.)^ </dd>
** size of each lookaside buffer slot ("sz") and the second is the number of
** slots allocated to each database connection ("cnt").)^
** ^(SQLITE_CONFIG_LOOKASIDE sets the <i>default</i> lookaside size.
** The [SQLITE_DBCONFIG_LOOKASIDE] option to [sqlite3_db_config()] can
** be used to change the lookaside configuration on individual connections.)^
** The [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to change the
** default lookaside configuration at compile-time.
** </dd>
**
** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is
@@ -2232,31 +2242,50 @@ struct sqlite3_mem_methods {
** [[SQLITE_DBCONFIG_LOOKASIDE]]
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
** <dd> The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the
** configuration of the lookaside memory allocator within a database
** configuration of the [lookaside memory allocator] within a database
** connection.
** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are <i>not</i>
** in the [DBCONFIG arguments|usual format].
** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two,
** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE
** should have a total of five parameters.
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
** <ol>
** <li><p>The first argument ("buf") is a
** pointer to a memory buffer to use for lookaside memory.
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
** may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
** size of each lookaside buffer slot. ^The third argument is the number of
** slots. The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments. The buffer
** must be aligned to an 8-byte boundary. ^If the second argument to
** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
** rounded down to the next smaller multiple of 8. ^(The lookaside memory
** The first argument may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()].
** <li><P>The second argument ("sz") is the
** size of each lookaside buffer slot. Lookaside is disabled if "sz"
** is less than 8. The "sz" argument should be a multiple of 8 less than
** 65536. If "sz" does not meet this constraint, it is reduced in size until
** it does.
** <li><p>The third argument ("cnt") is the number of slots. Lookaside is disabled
** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so
** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt"
** parameter is usually chosen so that the product of "sz" and "cnt" is less
** than 1,000,000.
** </ol>
** <p>If the "buf" argument is not NULL, then it must
** point to a memory buffer with a size that is greater than
** or equal to the product of "sz" and "cnt".
** The buffer must be aligned to an 8-byte boundary.
** The lookaside memory
** configuration for a database connection can only be changed when that
** connection is not currently using lookaside memory, or in other words
** when the "current value" returned by
** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero.
** when the value returned by [SQLITE_DBSTATUS_LOOKASIDE_USED] is zero.
** Any attempt to change the lookaside memory configuration when lookaside
** memory is in use leaves the configuration unchanged and returns
** [SQLITE_BUSY].)^</dd>
** [SQLITE_BUSY].
** If the "buf" argument is NULL and an attempt
** to allocate memory based on "sz" and "cnt" fails, then
** lookaside is silently disabled.
** <p>
** The [SQLITE_CONFIG_LOOKASIDE] configuration option can be used to set the
** default lookaside configuration at initialization. The
** [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to set the default lookaside
** configuration at compile-time. Typical values for lookaside are 1200 for
** "sz" and 40 to 100 for "cnt".
** </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
@@ -2993,6 +3022,44 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
*/
SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
/*
** CAPI3REF: Set the Setlk Timeout
** METHOD: sqlite3
**
** This routine is only useful in SQLITE_ENABLE_SETLK_TIMEOUT builds. If
** the VFS supports blocking locks, it sets the timeout in ms used by
** eligible locks taken on wal mode databases by the specified database
** handle. In non-SQLITE_ENABLE_SETLK_TIMEOUT builds, or if the VFS does
** not support blocking locks, this function is a no-op.
**
** Passing 0 to this function disables blocking locks altogether. Passing
** -1 to this function requests that the VFS blocks for a long time -
** indefinitely if possible. The results of passing any other negative value
** are undefined.
**
** Internally, each SQLite database handle store two timeout values - the
** busy-timeout (used for rollback mode databases, or if the VFS does not
** support blocking locks) and the setlk-timeout (used for blocking locks
** on wal-mode databases). The sqlite3_busy_timeout() method sets both
** values, this function sets only the setlk-timeout value. Therefore,
** to configure separate busy-timeout and setlk-timeout values for a single
** database handle, call sqlite3_busy_timeout() followed by this function.
**
** Whenever the number of connections to a wal mode database falls from
** 1 to 0, the last connection takes an exclusive lock on the database,
** then checkpoints and deletes the wal file. While it is doing this, any
** new connection that tries to read from the database fails with an
** SQLITE_BUSY error. Or, if the SQLITE_SETLK_BLOCK_ON_CONNECT flag is
** passed to this API, the new connection blocks until the exclusive lock
** has been released.
*/
SQLITE_API int sqlite3_setlk_timeout(sqlite3*, int ms, int flags);
/*
** CAPI3REF: Flags for sqlite3_setlk_timeout()
*/
#define SQLITE_SETLK_BLOCK_ON_CONNECT 0x01
/*
** CAPI3REF: Convenience Routines For Running Queries
** METHOD: sqlite3
@@ -5108,7 +5175,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]),
** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
@@ -7004,6 +7071,8 @@ SQLITE_API int sqlite3_autovacuum_pages(
**
** ^The second argument is a pointer to the function to invoke when a
** row is updated, inserted or deleted in a rowid table.
** ^The update hook is disabled by invoking sqlite3_update_hook()
** with a NULL pointer as the second parameter.
** ^The first argument to the callback is a copy of the third argument
** to sqlite3_update_hook().
** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
@@ -11486,9 +11555,10 @@ SQLITE_API void sqlite3session_table_filter(
** is inserted while a session object is enabled, then later deleted while
** the same session object is disabled, no INSERT record will appear in the
** changeset, even though the delete took place while the session was disabled.
** Or, if one field of a row is updated while a session is disabled, and
** another field of the same row is updated while the session is enabled, the
** resulting changeset will contain an UPDATE change that updates both fields.
** Or, if one field of a row is updated while a session is enabled, and
** then another field of the same row is updated while the session is disabled,
** the resulting changeset will contain an UPDATE change that updates both
** fields.
*/
SQLITE_API int sqlite3session_changeset(
sqlite3_session *pSession, /* Session object */
@@ -11560,8 +11630,9 @@ SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession
** database zFrom the contents of the two compatible tables would be
** identical.
**
** It an error if database zFrom does not exist or does not contain the
** required compatible table.
** Unless the call to this function is a no-op as described above, it is an
** error if database zFrom does not exist or does not contain the required
** compatible table.
**
** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite
** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
@@ -11696,7 +11767,7 @@ SQLITE_API int sqlite3changeset_start_v2(
** The following flags may passed via the 4th parameter to
** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
**
** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
** <dt>SQLITE_CHANGESETSTART_INVERT <dd>
** Invert the changeset while iterating through it. This is equivalent to
** inverting a changeset using sqlite3changeset_invert() before applying it.
** It is an error to specify this flag with a patchset.
@@ -12011,19 +12082,6 @@ SQLITE_API int sqlite3changeset_concat(
void **ppOut /* OUT: Buffer containing output changeset */
);
/*
** CAPI3REF: Upgrade the Schema of a Changeset/Patchset
*/
SQLITE_API int sqlite3changeset_upgrade(
sqlite3 *db,
const char *zDb,
int nIn, const void *pIn, /* Input changeset */
int *pnOut, void **ppOut /* OUT: Inverse of input */
);
/*
** CAPI3REF: Changegroup Handle
**

View File

@@ -366,6 +366,8 @@ struct sqlite3_api_routines {
/* Version 3.44.0 and later */
void *(*get_clientdata)(sqlite3*,const char*);
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
/* Version 3.50.0 and later */
int (*setlk_timeout)(sqlite3*,int,int);
};
/*
@@ -699,6 +701,8 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.44.0 and later */
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
/* Version 3.50.0 and later */
#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)

View File

@@ -14,7 +14,7 @@
- upload to Apple with dist-ios on macos
- nix
- june and december: update release version
- run `nix flake update`
- run `nix --extra-experimental-features nix-command --extra-experimental-features flakes flake update`
- comment out the hash in default.nix
- update the version
- run `nix-build`

6
flake.lock generated
View File

@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1745279238,
"narHash": "sha256-AQ7M9wTa/Pa/kK5pcGTgX/DGqMHyzsyINfN7ktsI7Fo=",
"lastModified": 1748037224,
"narHash": "sha256-92vihpZr6dwEMV6g98M5kHZIttrWahb9iRPBm1atcPk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9684b53175fc6c09581e94cc85f05ab77464c7e3",
"rev": "f09dede81861f3a83f7f06641ead34f02f37597f",
"type": "github"
},
"original": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unprompted.tildefriends"
android:versionCode="37"
android:versionName="0.0.31">
android:versionCode="38"
android:versionName="0.0.32-wip">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application

View File

@@ -13,13 +13,13 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.0.31</string>
<string>0.0.32</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>13</string>
<string>14</string>
<key>DTPlatformName</key>
<string>iphoneos</string>
<key>LSRequiresIPhoneOS</key>

View File

@@ -1,2 +1,2 @@
#define VERSION_NUMBER "0.0.31"
#define VERSION_NUMBER "0.0.32-wip"
#define VERSION_NAME "This program kills fascists."

View File

@@ -124,7 +124,7 @@ try:
select(driver, ['tf-navigation', 'shadow_root', '#close_error'], ('click',))
select(driver, ['tf-navigation', 'shadow_root', '=edit'], ('click',))
select(driver, ['#editor', '.cm-content'], ('click',))
select(driver, ['#editor', '.cm-content'], ('send_keys', 'app.setDocument(\n\t"<div id=\'test-div\'>Hello, world!</div>"\n);'))
select(driver, ['#editor', '.cm-content'], ('send_keys', 'app.setDocument(\n\t`<div id=\'test-div\' style=\'color: white; font-size: xx-large\'>\n\t\tHello, world!\n\t</div>`\n);'))
select(driver, ['#save'], ('click',))
select(driver, ['#document', 'frame', '#test-div'])