7 Commits

Author SHA1 Message Date
68aa41ab96 android: Tweaking random flags until ANRs subside.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 30m34s
2025-08-02 12:09:08 -04:00
85b23437b3 docs: Fix all the TODOCS. #39
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m17s
2025-08-02 09:07:45 -04:00
c59fba817d ssb: Show the progress indicator more consistently.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 30m54s
2025-07-31 12:48:45 -04:00
c3415ab75c docs: Expose the rest of core to docs.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m24s
2025-07-30 20:25:20 -04:00
f1d0151d71 ssb: Make the progress bar more indefinite-looking.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-07-30 20:04:34 -04:00
3c5c1756d1 ssb: A progress bar experiment. 2025-07-30 19:49:08 -04:00
6a6b65d1b3 build: Update nix config. Start building 0.2025.8, switching to calver.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-07-30 19:26:26 -04:00
15 changed files with 180 additions and 98 deletions

View File

@@ -16,9 +16,9 @@ MAKEFLAGS += --no-builtin-rules
## LD := Linker. ## LD := Linker.
## ANDROID_SDK := Path to the Android SDK. ## ANDROID_SDK := Path to the Android SDK.
VERSION_CODE := 40 VERSION_CODE := 41
VERSION_CODE_IOS := 15 VERSION_CODE_IOS := 16
VERSION_NUMBER := 0.0.33 VERSION_NUMBER := 0.2025.8-wip
VERSION_NAME := This program kills fascists. VERSION_NAME := This program kills fascists.
IPHONEOS_VERSION_MIN=14.0 IPHONEOS_VERSION_MIN=14.0

View File

@@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🦀", "emoji": "🦀",
"previous": "&DGtlnm5wWRZCgJMF8JsP6VtzNRrd4KLoERJRpFULqOY=.sha256" "previous": "&nvdIMraZtEjSegUCd4b5hLz6Csn5YNV+vyJWu7QAE3I=.sha256"
} }

View File

@@ -25,6 +25,7 @@ class TfElement extends LitElement {
recent_reactions: {type: Array}, recent_reactions: {type: Array},
is_administrator: {type: Boolean}, is_administrator: {type: Boolean},
stay_connected: {type: Boolean}, stay_connected: {type: Boolean},
progress: {type: Number},
}; };
} }
@@ -56,6 +57,7 @@ class TfElement extends LitElement {
tfrpc.rpc.getHash().then((hash) => self.set_hash(hash)); tfrpc.rpc.getHash().then((hash) => self.set_hash(hash));
tfrpc.register(function hashChanged(hash) { tfrpc.register(function hashChanged(hash) {
self.set_hash(hash); self.set_hash(hash);
self.reset_progress();
}); });
tfrpc.register(async function notifyNewMessage(id) { tfrpc.register(async function notifyNewMessage(id) {
await self.fetch_new_message(id); await self.fetch_new_message(id);
@@ -450,7 +452,28 @@ class TfElement extends LitElement {
this.schedule_load_latest(); this.schedule_load_latest();
} }
reset_progress() {
if (this.progress === undefined) {
this._progress_start = new Date();
requestAnimationFrame(this.update_progress.bind(this));
}
}
update_progress() {
if (
!this.loading_latest &&
!this.loading_latest_scheduled &&
!this.shadowRoot.getElementById('tf-tab-news')?.is_loading()
) {
this.progress = undefined;
return;
}
this.progress = (new Date() - this._progress_start).valueOf();
requestAnimationFrame(this.update_progress.bind(this));
}
schedule_load_latest() { schedule_load_latest() {
this.reset_progress();
if (!this.loading_latest) { if (!this.loading_latest) {
this.shadowRoot.getElementById('tf-tab-news')?.load_latest(); this.shadowRoot.getElementById('tf-tab-news')?.load_latest();
this.load(); this.load();
@@ -495,6 +518,7 @@ class TfElement extends LitElement {
async load() { async load() {
this.loading_latest = true; this.loading_latest = true;
this.reset_progress();
try { try {
let start_time = new Date(); let start_time = new Date();
let whoami = this.whoami; let whoami = this.whoami;
@@ -603,6 +627,7 @@ class TfElement extends LitElement {
@channelsetunread=${this.channel_set_unread} @channelsetunread=${this.channel_set_unread}
@refresh=${this.refresh} @refresh=${this.refresh}
@toggle_stay_connected=${this.toggle_stay_connected} @toggle_stay_connected=${this.toggle_stay_connected}
@loadmessages=${this.reset_progress}
.connections=${this.connections} .connections=${this.connections}
.private_messages=${this.private_messages} .private_messages=${this.private_messages}
.recent_reactions=${this.recent_reactions} .recent_reactions=${this.recent_reactions}
@@ -646,6 +671,7 @@ class TfElement extends LitElement {
async set_tab(tab) { async set_tab(tab) {
this.tab = tab; this.tab = tab;
if (tab === 'news') { if (tab === 'news') {
this.schedule_load_latest();
await tfrpc.rpc.setHash('#'); await tfrpc.rpc.setHash('#');
} else if (tab === 'connections') { } else if (tab === 'connections') {
await tfrpc.rpc.setHash('#connections'); await tfrpc.rpc.setHash('#connections');
@@ -751,11 +777,23 @@ class TfElement extends LitElement {
Loading... Loading...
</div>` </div>`
: this.render_tab(); : this.render_tab();
let progress =
this.progress !== undefined
? html`
<div style="position: absolute; width: 100%" id="progress">
<div
class="w3-theme-l2"
style=${`height: 4px; position: absolute; right: ${Math.cos(this.progress / 250) > 0 ? 'auto' : '0'}; width: ${50 * Math.sin(this.progress / 250) + 50}%`}
></div>
</div>
`
: undefined;
return html` return html`
<div <div
style="width: 100vw; min-height: 100vh; height: 100vh; display: flex; flex-direction: column" style="width: 100vw; min-height: 100vh; height: 100vh; display: flex; flex-direction: column"
class="w3-theme-dark" class="w3-theme-dark"
> >
${progress}
<div style="flex: 0 0">${tabs}</div> <div style="flex: 0 0">${tabs}</div>
<div style="flex: 1 1; overflow: auto; contain: layout"> <div style="flex: 1 1; overflow: auto; contain: layout">
${contents} ${contents}

View File

@@ -106,6 +106,12 @@ class TfTabNewsFeedElement extends LitElement {
} }
async fetch_messages(start_time, end_time) { async fetch_messages(start_time, end_time) {
this.dispatchEvent(
new CustomEvent('loadmessages', {
bubbles: true,
composed: true,
})
);
this.time_loading = [start_time, end_time]; this.time_loading = [start_time, end_time];
let result; let result;
const k_max_results = 64; const k_max_results = 64;

View File

@@ -180,6 +180,10 @@ class TfTabNewsElement extends LitElement {
await this.check_peer_exchange(); await this.check_peer_exchange();
} }
is_loading() {
return this.shadowRoot?.getElementById('news')?.loading;
}
render_sidebar() { render_sidebar() {
return html` return html`
<div <div

View File

@@ -1,7 +1,23 @@
/**
* \file
* \defgroup tfapp Tilde Friends App JS
* Tilde Friends server-side app wrapper.
* @{
*/
/** \cond */
import * as core from './core.js'; import * as core from './core.js';
let gSessionIndex = 0; export {App};
/** \endcond */
/** A sequence number of apps. */
let g_session_index = 0;
/**
** App constructor.
** @return An app instance.
*/
function App() { function App() {
this._send_queue = []; this._send_queue = [];
this.calls = {}; this.calls = {};
@@ -9,6 +25,12 @@ function App() {
return this; return this;
} }
/**
** Create a function wrapper that when called invokes a function on the app
** itself.
** @param api The function and argument names.
** @return A function.
*/
App.prototype.makeFunction = function (api) { App.prototype.makeFunction = function (api) {
let self = this; let self = this;
let result = function () { let result = function () {
@@ -32,6 +54,10 @@ App.prototype.makeFunction = function (api) {
return result; return result;
}; };
/**
** Send a message to the app.
** @param message The message to send.
*/
App.prototype.send = function (message) { App.prototype.send = function (message) {
if (this._send_queue) { if (this._send_queue) {
if (this._on_output) { if (this._on_output) {
@@ -46,6 +72,11 @@ App.prototype.send = function (message) {
} }
}; };
/**
** App socket handler.
** @param request The HTTP request of the WebSocket connection.
** @param response The HTTP response.
*/
exports.app_socket = async function socket(request, response) { exports.app_socket = async function socket(request, response) {
let process; let process;
let options = {}; let options = {};
@@ -133,7 +164,7 @@ exports.app_socket = async function socket(request, response) {
options.packageOwner = packageOwner; options.packageOwner = packageOwner;
options.packageName = packageName; options.packageName = packageName;
options.url = message.url; options.url = message.url;
let sessionId = 'session_' + (gSessionIndex++).toString(); let sessionId = 'session_' + (g_session_index++).toString();
if (blobId) { if (blobId) {
if (message.edit_only) { if (message.edit_only) {
response.send( response.send(
@@ -218,4 +249,4 @@ exports.app_socket = async function socket(request, response) {
response.upgrade(100, {}); response.upgrade(100, {});
}; };
export {App}; /** @} */

View File

@@ -72,7 +72,7 @@ class TfNavigationElement extends LitElement {
} }
/** /**
* TODOC * Toggle editor visibility.
* @param event The HTML event. * @param event The HTML event.
*/ */
toggle_edit(event) { toggle_edit(event) {
@@ -85,7 +85,7 @@ class TfNavigationElement extends LitElement {
} }
/** /**
* TODOC * Remove a stored permission.
* @param key The permission to reset. * @param key The permission to reset.
*/ */
reset_permission(key) { reset_permission(key) {
@@ -93,7 +93,7 @@ class TfNavigationElement extends LitElement {
} }
/** /**
* TODOC * Get or create a spark line.
* @param key The spark line identifier. * @param key The spark line identifier.
* @param options Spark line options. * @param options Spark line options.
* @return A spark line HTML element. * @return A spark line HTML element.
@@ -262,8 +262,8 @@ class TfNavigationElement extends LitElement {
} }
/** /**
* TODOC * Render the permissions popup.
* @returns * @return Lit HTML.
*/ */
render_permissions() { render_permissions() {
if (this.show_permissions) { if (this.show_permissions) {
@@ -312,8 +312,8 @@ class TfNavigationElement extends LitElement {
} }
/** /**
* TODOC * Render the navigation bar.
* @returns * @return Lit HTML.
*/ */
render() { render() {
let self = this; let self = this;
@@ -441,7 +441,7 @@ class TfNavigationElement extends LitElement {
customElements.define('tf-navigation', TfNavigationElement); customElements.define('tf-navigation', TfNavigationElement);
/** /**
* TODOC * A file in the files sidebar.
*/ */
class TfFilesElement extends LitElement { class TfFilesElement extends LitElement {
/** /**
@@ -467,7 +467,7 @@ class TfFilesElement extends LitElement {
} }
/** /**
* TODOC * Select a clicked file.
* @param file The file. * @param file The file.
*/ */
file_click(file) { file_click(file) {
@@ -483,9 +483,9 @@ class TfFilesElement extends LitElement {
} }
/** /**
* TODOC * Render a single file in the file list.
* @param file The file. * @param file The file.
* @returns Lit HTML. * @return Lit HTML.
*/ */
render_file(file) { render_file(file) {
let classes = ['file']; let classes = ['file'];
@@ -507,7 +507,7 @@ class TfFilesElement extends LitElement {
} }
/** /**
* TODOC * Create a file entry for a dropped file.
* @param event The event. * @param event The event.
*/ */
async drop(event) { async drop(event) {
@@ -533,7 +533,7 @@ class TfFilesElement extends LitElement {
} }
/** /**
* TODOC * Called when a file starts being dragged over the file.
* @param event The event. * @param event The event.
*/ */
drag_enter(event) { drag_enter(event) {
@@ -543,7 +543,7 @@ class TfFilesElement extends LitElement {
} }
/** /**
* TODOC * Called when a file stops being dragged over the file.
* @param event The event. * @param event The event.
*/ */
drag_leave(event) { drag_leave(event) {
@@ -554,7 +554,7 @@ class TfFilesElement extends LitElement {
} }
/** /**
* Drag over event. * Called when a file is being dragged over the file.
* @param event The event. * @param event The event.
*/ */
drag_over(event) { drag_over(event) {
@@ -562,8 +562,8 @@ class TfFilesElement extends LitElement {
} }
/** /**
* TODOC * Render the file.
* @returns * @return Lit HTML.
*/ */
render() { render() {
let self = this; let self = this;
@@ -610,7 +610,7 @@ class TfFilesElement extends LitElement {
customElements.define('tf-files', TfFilesElement); customElements.define('tf-files', TfFilesElement);
/** /**
* TODOC * The files pane element.
*/ */
class TfFilesPaneElement extends LitElement { class TfFilesPaneElement extends LitElement {
/** /**
@@ -635,7 +635,7 @@ class TfFilesPaneElement extends LitElement {
} }
/** /**
* TODOC * Set whether the files pane is expanded.
* @param expanded Whether the files pane is expanded. * @param expanded Whether the files pane is expanded.
*/ */
set_expanded(expanded) { set_expanded(expanded) {
@@ -644,8 +644,8 @@ class TfFilesPaneElement extends LitElement {
} }
/** /**
* TODOC * Render the files pane element.
* @returns * @return Lit HTML.
*/ */
render() { render() {
let self = this; let self = this;
@@ -704,7 +704,7 @@ class TfFilesPaneElement extends LitElement {
customElements.define('tf-files-pane', TfFilesPaneElement); customElements.define('tf-files-pane', TfFilesPaneElement);
/** /**
* TODOC * A tiny graph.
*/ */
class TfSparkLineElement extends LitElement { class TfSparkLineElement extends LitElement {
static get properties() { static get properties() {
@@ -724,9 +724,9 @@ class TfSparkLineElement extends LitElement {
} }
/** /**
* TODOC * Add a data point to the graph.
* @param {*} key * @param key The line to which the point applies.
* @param {*} value * @param value The numeric value of the data point.
*/ */
append(key, value) { append(key, value) {
let line = null; let line = null;
@@ -753,9 +753,9 @@ class TfSparkLineElement extends LitElement {
} }
/** /**
* TODOC * Render a single series line.
* @param {*} line * @param line The line data.
* @returns * @return Lit HTML.
*/ */
render_line(line) { render_line(line) {
if (line?.values?.length >= 2) { if (line?.values?.length >= 2) {
@@ -771,8 +771,8 @@ class TfSparkLineElement extends LitElement {
} }
/** /**
* TODOC * Render the graph.
* @returns * @return Lit HTML.
*/ */
render() { render() {
let max = let max =
@@ -799,7 +799,9 @@ class TfSparkLineElement extends LitElement {
customElements.define('tf-sparkline', TfSparkLineElement); customElements.define('tf-sparkline', TfSparkLineElement);
// TODOC /**
* A keyboard key is pressed down.
*/
window.addEventListener('keydown', function (event) { window.addEventListener('keydown', function (event) {
if (event.keyCode == 83 && (event.altKey || event.ctrlKey)) { if (event.keyCode == 83 && (event.altKey || event.ctrlKey)) {
if (editing()) { if (editing()) {
@@ -860,24 +862,23 @@ function ensureLoaded(nodes, callback) {
} }
/** /**
* TODOC * Check whether the editior is currently visible.
* @returns * @return true if the editor is visible.
*/ */
function editing() { function editing() {
return document.getElementById('editPane').style.display != 'none'; return document.getElementById('editPane').style.display != 'none';
} }
/** /**
* TODOC * Check whether only the editor is visible and the app is hidden.
* @returns * @return true if the editor is visible and the app is not.
*/ */
function is_edit_only() { function is_edit_only() {
return window.location.search == '?editonly=1' || window.innerWidth < 1024; return window.location.search == '?editonly=1' || window.innerWidth < 1024;
} }
/** /**
* TODOC * Show the editor.
* @returns
*/ */
async function edit() { async function edit() {
if (editing()) { if (editing()) {
@@ -904,7 +905,7 @@ async function edit() {
} }
/** /**
* TODOC * Open a performance trace.
*/ */
function trace() { function trace() {
window.open(`/speedscope/#profileURL=${encodeURIComponent('/trace')}`); window.open(`/speedscope/#profileURL=${encodeURIComponent('/trace')}`);
@@ -982,7 +983,7 @@ async function load(path) {
} }
/** /**
* TODOC * Hide the editor.
*/ */
function closeEditor() { function closeEditor() {
window.localStorage.setItem('editing', '0'); window.localStorage.setItem('editing', '0');
@@ -990,14 +991,6 @@ function closeEditor() {
document.getElementById('viewPane').style.display = 'flex'; document.getElementById('viewPane').style.display = 'flex';
} }
/**
* TODOC
* @returns
*/
function explodePath() {
return /^\/~([^\/]+)\/([^\/]+)(.*)/.exec(window.location.pathname);
}
/** /**
* Save the app. * Save the app.
* @param save_to An optional path to which to save the app. * @param save_to An optional path to which to save the app.
@@ -1111,7 +1104,7 @@ function save(save_to) {
} }
/** /**
* TODOC * Prompt to set the app icon.
*/ */
function changeIcon() { function changeIcon() {
let value = prompt('Enter a new app icon emoji:'); let value = prompt('Enter a new app icon emoji:');
@@ -1122,7 +1115,7 @@ function changeIcon() {
} }
/** /**
* TODOC * Prompt to delete the current app.
*/ */
function deleteApp() { function deleteApp() {
let name = document.getElementById('name'); let name = document.getElementById('name');
@@ -1143,8 +1136,8 @@ function deleteApp() {
} }
/** /**
* TODOC * Get the current app URL.
* @returns * @return The app URL.
*/ */
function url() { function url() {
let hash = window.location.href.indexOf('#'); let hash = window.location.href.indexOf('#');
@@ -1162,8 +1155,8 @@ function url() {
} }
/** /**
* TODOC * Get the window hash without the lone '#' if it is empty.
* @returns * @return The hash.
*/ */
function hash() { function hash() {
return window.location.hash != '#' ? window.location.hash : ''; return window.location.hash != '#' ? window.location.hash : '';
@@ -1188,7 +1181,7 @@ function api_postMessage(message) {
} }
/** /**
* TODOC * Show an error.
* @param error The error. * @param error The error.
*/ */
function api_error(error) { function api_error(error) {
@@ -1293,7 +1286,7 @@ function api_requestPermission(permission, id) {
} }
/** /**
* TODOC * Log from the app to the console.
*/ */
function api_print() { function api_print() {
console.log('app>', ...arguments); console.log('app>', ...arguments);
@@ -1308,7 +1301,7 @@ function api_setHash(hash) {
} }
/** /**
* TODOC * Process an incoming WebSocket message.
* @param message The message. * @param message The message.
*/ */
function _receive_websocket_message(message) { function _receive_websocket_message(message) {
@@ -1432,14 +1425,14 @@ function send(value) {
} }
/** /**
* TODOC * Notify the app of the window hash changing.
*/ */
function hashChange() { function hashChange() {
send({event: 'hashChange', hash: window.location.hash}); send({event: 'hashChange', hash: window.location.hash});
} }
/** /**
* TODOC * Make sure the app is connected on window focus, and notify the app.
*/ */
function focus() { function focus() {
if (gSocket && gSocket.readyState == gSocket.CLOSED) { if (gSocket && gSocket.readyState == gSocket.CLOSED) {
@@ -1450,7 +1443,7 @@ function focus() {
} }
/** /**
* TODOC * Notify the app of lost focus.
*/ */
function blur() { function blur() {
if (gSocket && gSocket.readyState == gSocket.OPEN) { if (gSocket && gSocket.readyState == gSocket.OPEN) {
@@ -1617,7 +1610,7 @@ function openFile(name) {
} }
/** /**
* TODOC * Refresh the files list.
*/ */
function updateFiles() { function updateFiles() {
let files = document.getElementsByTagName('tf-files-pane')[0]; let files = document.getElementsByTagName('tf-files-pane')[0];
@@ -1650,7 +1643,7 @@ function makeNewFile(name) {
} }
/** /**
* TODOC * Prompt to create a new file.
*/ */
function newFile() { function newFile() {
let name = prompt('Name of new file:', 'file.js'); let name = prompt('Name of new file:', 'file.js');
@@ -1660,7 +1653,7 @@ function newFile() {
} }
/** /**
* TODOC * Prompt to remove a file.
*/ */
function removeFile() { function removeFile() {
if (confirm('Remove ' + gCurrentFile + '?')) { if (confirm('Remove ' + gCurrentFile + '?')) {
@@ -1670,7 +1663,7 @@ function removeFile() {
} }
/** /**
* TODOC * Export the app to a zip file, which is downloaded by the browser.
*/ */
async function appExport() { async function appExport() {
let JsZip = (await import('/static/jszip.min.js')).default; let JsZip = (await import('/static/jszip.min.js')).default;
@@ -1728,7 +1721,7 @@ async function save_file_to_blob_id(name, file) {
} }
/** /**
* TODOC * Prompt to import an app from a zip file.
*/ */
async function appImport() { async function appImport() {
let JsZip = (await import('/static/jszip.min.js')).default; let JsZip = (await import('/static/jszip.min.js')).default;
@@ -1855,7 +1848,9 @@ function toggleVisibleWhitespace() {
} }
} }
// TODOC /**
* Register event handlers and connect the WebSocket on load.
*/
window.addEventListener('load', function () { window.addEventListener('load', function () {
window.addEventListener('hashchange', hashChange); window.addEventListener('hashchange', hashChange);
window.addEventListener('focus', focus); window.addEventListener('focus', focus);

View File

@@ -1,8 +1,14 @@
/** /**
* TODOC * \file
* TODO: document so we can improve this * \defgroup tfhttp Tilde Friends HTTP Client JS
* @param {*} url * Tilde Friends server-side HTTP client.
* @returns * @{
*/
/**
* Parse a URL into protocol, host, path, and port parts.
* @param url
* @return An object of the URL parts.
*/ */
function parseUrl(url) { function parseUrl(url) {
// XXX: Hack. // XXX: Hack.
@@ -16,9 +22,9 @@ function parseUrl(url) {
} }
/** /**
* TODOC * Parse an HTTP response into headers and body content.
* @param {*} data * @param data The response data, headers and body included.
* @returns * @return headers and body data.
*/ */
function parseResponse(data) { function parseResponse(data) {
let firstLine; let firstLine;
@@ -36,15 +42,15 @@ function parseResponse(data) {
headers[line.substring(colon)] = line.substring(colon + 1); headers[line.substring(colon)] = line.substring(colon + 1);
} }
} }
return {body: data}; return {headers: headers, body: data};
} }
/** /**
* TODOC * Make an HTTP request.
* @param {*} url * @param url The URL.
* @param {*} options * @param options Request options.
* @param {*} allowed_hosts * @param allowed_hosts List of allowed hosts.
* @returns * @return A promise resolved with the response headers and body.
*/ */
export function fetch(url, options, allowed_hosts) { export function fetch(url, options, allowed_hosts) {
let parsed = parseUrl(url); let parsed = parseUrl(url);
@@ -111,3 +117,5 @@ export function fetch(url, options, allowed_hosts) {
}); });
}); });
} }
/** @} */

View File

@@ -15,8 +15,8 @@ let g_next_id = 1;
let g_calls = {}; let g_calls = {};
/** /**
* TODOC * Check if being called from a browser vs. server-side.
* @returns * @return true if called from a browser.
*/ */
function get_is_browser() { function get_is_browser() {
try { try {

View File

@@ -25,14 +25,14 @@
}: }:
pkgs.stdenv.mkDerivation rec { pkgs.stdenv.mkDerivation rec {
pname = "tildefriends"; pname = "tildefriends";
version = "0.0.32"; version = "0.0.33";
src = pkgs.fetchFromGitea { src = pkgs.fetchFromGitea {
domain = "dev.tildefriends.net"; domain = "dev.tildefriends.net";
owner = "cory"; owner = "cory";
repo = "tildefriends"; repo = "tildefriends";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-Dk0NOEQIg2LeENySK0+MgpZEtfsClGq6dZL+eOOpE0U="; hash = "sha256-9D28gmaBTRVyXhY3zZd/W9PsXA1YZt/K69hz41aVP04=";
fetchSubmodules = true; fetchSubmodules = true;
}; };

6
flake.lock generated
View File

@@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1750622754, "lastModified": 1753749649,
"narHash": "sha256-kMhs+YzV4vPGfuTpD3mwzibWUE6jotw5Al2wczI0Pv8=", "narHash": "sha256-+jkEZxs7bfOKfBIk430K+tK9IvXlwzqQQnppC2ZKFj4=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c7ab75210cb8cb16ddd8f290755d9558edde7ee1", "rev": "1f08a4df998e21f4e8be8fb6fbf61d11a1a5076a",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

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

View File

@@ -426,7 +426,7 @@ public class TildeFriendsActivity extends Activity {
Log.w("tildefriends", "onServiceDisconnected"); Log.w("tildefriends", "onServiceDisconnected");
} }
}; };
s_activity.bindService(intent, s_activity.service_connection, BIND_AUTO_CREATE); s_activity.bindService(intent, s_activity.service_connection, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND);
} }
public static void stop_sandbox() { public static void stop_sandbox() {

View File

@@ -13,13 +13,13 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.0.33</string> <string>0.2025.8</string>
<key>CFBundleSupportedPlatforms</key> <key>CFBundleSupportedPlatforms</key>
<array> <array>
<string>iPhoneOS</string> <string>iPhoneOS</string>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>15</string> <string>16</string>
<key>DTPlatformName</key> <key>DTPlatformName</key>
<string>iphoneos</string> <string>iphoneos</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>

View File

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