10 Commits

Author SHA1 Message Date
8cc4c19d73 Prettier and generated files I've missed.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 16m45s
2024-09-30 12:15:27 -04:00
bb9c18faf1 Some missing log newlines. 2024-09-30 12:13:57 -04:00
fabdfb76b9 android: readParcelable compatibility.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 16m37s
2024-09-29 08:18:46 -04:00
bce263a928 android: Use FileObserver, which is actually compatible with api level 24 which we claim to support.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 15m39s
2024-09-29 00:17:38 -04:00
195920e476 android: Avoid a ClosedWatchServiceException.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 16m40s
2024-09-28 23:25:28 -04:00
a821d895c5 docs: Give working advice on how to get the tree and dependencies.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 16m3s
2024-09-28 07:11:47 -04:00
ab1b6ec27d build: Add a dependency off appimagetool??
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 17m34s
2024-09-27 22:10:01 -04:00
6dc099809f build: This creates a working AppImage.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2024-09-27 21:19:18 -04:00
03c8b75994 Let's start work on 0.0.24.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 18m37s
2024-09-25 20:26:57 -04:00
38887452ad nix => 0.0.23.
Some checks are pending
Build Tilde Friends / Build-All (push) Waiting to run
2024-09-25 20:20:14 -04:00
12 changed files with 110 additions and 96 deletions

View File

@ -24,7 +24,7 @@ jobs:
uses: android-actions/setup-android@v3 uses: android-actions/setup-android@v3
with: with:
packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264' packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264'
- run: sudo apt update && sudo apt install -y doxygen graphviz mingw-w64 - run: sudo apt update && sudo apt install -y doxygen graphviz mingw-w64 libgpgme11
- run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all docs - run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all docs
- run: docker build . - run: docker build .
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v3

View File

@ -3,14 +3,14 @@
MAKEFLAGS += --warn-undefined-variables MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules MAKEFLAGS += --no-builtin-rules
VERSION_CODE := 27 VERSION_CODE := 28
VERSION_NUMBER := 0.0.23 VERSION_NUMBER := 0.0.24-wip
VERSION_NAME := Me upon my pony on my boat. VERSION_NAME := Honey bunches of boats.
SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3460100.zip SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3460100.zip
BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar
LINUXDEPLOY_URL := https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20240109-1/linuxdeploy-x86_64.AppImage APPIMAGETOOL_URL := https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
LINUXDEPLOY_MD5 := 659d69326199524552bfbbe46cb0adae out/linuxdeploy APPIMAGETOOL_MD5 := e989fadfc4d685fd3d6aeeb9b525d74d out/appimagetool
PROJECT = tildefriends PROJECT = tildefriends
BUILD_DIR ?= out BUILD_DIR ?= out
@ -1077,17 +1077,22 @@ endif
out/tildefriends-x86_64.AppImage: out/release/tildefriends out/data.zip out/tildefriends-x86_64.AppImage: out/release/tildefriends out/data.zip
@echo "[appimage] $$@" @echo "[appimage] $$@"
@mkdir -p out/AppDir/usr/bin @rm -rf out/tildefriends.AppDir
@mkdir -p out/AppDir/usr/share/applications @mkdir -p out/tildefriends.AppDir/usr/bin
@mkdir -p out/AppDir/usr/share/icons/hicolor/scalable/apps @mkdir -p out/tildefriends.AppDir/usr/share/applications
@echo $(LINUXDEPLOY_MD5) > out/linuxdeploy.md5 @mkdir -p out/tildefriends.AppDir/usr/share/icons/hicolor/scalable/apps
@test -x out/linuxdeploy || curl -q -L -o out/linuxdeploy $(LINUXDEPLOY_URL) && md5sum -c out/linuxdeploy.md5 && chmod +x out/linuxdeploy @mkdir -p out/tildefriends.AppDir/usr/share/tildefriends
@echo "[Desktop Entry]\nName=tildefriends\nExec=tildefriends\nIcon=tildefriends\nType=Application\nCategories=Network" > out/AppDir/usr/share/applications/tildefriends.desktop @echo $(APPIMAGETOOL_MD5) > out/appimagetool.md5
@cp src/ios/tildefriends.svg out/AppDir/usr/share/icons/hicolor/scalable/apps/ @test -x out/appimagetool || curl -q -L -o out/appimagetool $(APPIMAGETOOL_URL) && md5sum -c out/appimagetool.md5 && chmod +x out/appimagetool
@cat out/release/tildefriends out/data.zip > out/AppDir/usr/bin/tildefriends @echo "[Desktop Entry]\nName=tildefriends\nExec=/usr/bin/tildefriends\nIcon=/usr/share/icons/hicolor/scalable/apps/tildefriends\nType=Application\nCategories=Network" > out/tildefriends.AppDir/tildefriends.desktop
@chmod +x out/AppDir/usr/bin/tildefriends @cp src/ios/tildefriends.svg out/tildefriends.AppDir/usr/share/icons/hicolor/scalable/apps/
@cd out; ./linuxdeploy --appimage-extract; cd .. @cp src/ios/tildefriends.svg out/tildefriends.AppDir/
@unset SOURCE_DATE_EPOCH; cd out; squashfs-root/usr/bin/linuxdeploy --appdir AppDir --output appimage; cd .. @cp out/release/tildefriends out/tildefriends.AppDir/usr/bin/
@cp out/data.zip out/tildefriends.AppDir/usr/share/tildefriends/data.zip
@echo "#!/bin/sh\n\$${APPDIR}/usr/bin/tildefriends run -z \$$APPDIR/usr/share/tildefriends/data.zip" > out/tildefriends.AppDir/AppRun
@chmod +x out/tildefriends.AppDir/AppRun
@cd out; ./appimagetool --appimage-extract; cd ..
@unset SOURCE_DATE_EPOCH; PATH=$$PATH:out/squashfs-root/usr/bin ARCH=x86_64 out/squashfs-root/usr/bin/appimagetool out/tildefriends.AppDir out/tildefriends-x86_64.AppImage
appimage: out/tildefriends-x86_64.AppImage appimage: out/tildefriends-x86_64.AppImage
.PHONY: appimage .PHONY: appimage

View File

@ -19,8 +19,27 @@ Scuttlebutt, as well as a platform for writing and running web applications.
Builds on Linux (x86_64 and aarch64), MacOS, OpenBSD, and Haiku. Builds for Builds on Linux (x86_64 and aarch64), MacOS, OpenBSD, and Haiku. Builds for
all of those host platforms plus mingw64, iOS, and android. all of those host platforms plus mingw64, iOS, and android.
1. Requires openssl (`libssl-dev`, in debian-speak). All other dependencies Tilde Friends uses git submodules, so either:
are kept up to date in the tree.
```
git clone --recurse-submodules https://dev.tildefriends.net/cory/tildefriends.git
```
or:
```
git clone https://dev.tildefriends.net/cory/tildefriends.git
cd tildefriends
git submodule update --init --recursive
```
The `.tar.xz` releases are all-inclusive.
The gitea `Source Code (ZIP)` and `Source Code (TAR.GZ)` are missing
dependencies, so don't use those.
1. On Linux only, system OpenSSL libraries (`libssl-dev`, in debian-speak) is
assumed to be available.
2. To build, run `make debug` or `make release`. An executable will be 2. To build, run `make debug` or `make release`. An executable will be
generated in a subdirectory of `out/`. generated in a subdirectory of `out/`.
3. It's possible to build for Android, iOS, and Windows on Linux, if you have 3. It's possible to build for Android, iOS, and Windows on Linux, if you have

View File

@ -73,16 +73,17 @@ class TfMessageElement extends LitElement {
} }
} }
if (this.message?.votes?.length) { if (this.message?.votes?.length) {
return html` return html` <div class="w3-container">
<div class="w3-container"> <div
<div class="w3-button w3-bar w3-padding-small" @click=${this.show_reactions}> class="w3-button w3-bar w3-padding-small"
@click=${this.show_reactions}
>
${(this.message.votes || []).map( ${(this.message.votes || []).map(
(vote) => html` (vote) => html`
<span <span
class="w3-bar-item w3-padding-small" class="w3-bar-item w3-padding-small"
title="${this.users[vote.author]?.name ?? vote.author} ${new Date( title="${this.users[vote.author]?.name ??
vote.timestamp vote.author} ${new Date(vote.timestamp)}"
)}"
> >
${normalize_expression(vote.content.vote.expression)} ${normalize_expression(vote.content.vote.expression)}
</span> </span>

View File

@ -69,7 +69,10 @@
><i class="fa fa-mug-hot"></i> Code</a ><i class="fa fa-mug-hot"></i> Code</a
> >
<p> <p>
<a href="https://f-droid.org/en/packages/com.unprompted.tildefriends.fdroid/"><img src="f-droid.svg" style="height: 3em"></a> <a
href="https://f-droid.org/en/packages/com.unprompted.tildefriends.fdroid/"
><img src="f-droid.svg" style="height: 3em"
/></a>
</p> </p>
</div> </div>
<div class="w3-col l4 m6"> <div class="w3-col l4 m6">

View File

@ -21,14 +21,14 @@
}: }:
pkgs.stdenv.mkDerivation rec { pkgs.stdenv.mkDerivation rec {
pname = "tildefriends"; pname = "tildefriends";
version = "0.0.22"; version = "0.0.23";
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-Su+y++zVXmYNbwfhCP6w5e36oxW5fkURPFzFLjbyFEI="; hash = "sha256-ukZpi+BXRTFGbdvd5ApmctTo8bjtPJMHjqFPgVSyBWU=";
fetchSubmodules = true; fetchSubmodules = true;
}; };

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="27" android:versionCode="28"
android:versionName="0.0.23"> android:versionName="0.0.24-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

@ -11,6 +11,7 @@ import android.net.ConnectivityManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.FileObserver;
import android.os.IBinder; import android.os.IBinder;
import android.os.Parcel; import android.os.Parcel;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
@ -42,12 +43,6 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileReader; import java.io.FileReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class TildeFriendsActivity extends Activity { public class TildeFriendsActivity extends Activity {
@ -55,9 +50,9 @@ public class TildeFriendsActivity extends Activity {
TildeFriendsWebView web_view; TildeFriendsWebView web_view;
String base_url; String base_url;
String port_file_path; String port_file_path;
Thread thread;
Thread server_thread; Thread server_thread;
ServiceConnection service_connection; ServiceConnection service_connection;
FileObserver observer;
private ValueCallback<Uri[]> upload_message; private ValueCallback<Uri[]> upload_message;
private final static int FILECHOOSER_RESULT = 1; private final static int FILECHOOSER_RESULT = 1;
@ -95,56 +90,9 @@ public class TildeFriendsActivity extends Activity {
TildeFriendsActivity activity = this; TildeFriendsActivity activity = this;
thread = new Thread(new Runnable() { Log.w("tildefriends", "Watching for changes in: " + getFilesDir().toString());
@Override observer = make_file_observer(getFilesDir().toString(), port_file_path);
public void run() { observer.startWatching();
Log.w("tildefriends", "Watching for changes in: " + getFilesDir().toString());
try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
Paths.get(getFilesDir().toString()).register(
watcher,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
WatchKey key = watcher.poll(100, TimeUnit.MILLISECONDS);
boolean attempt_it = true;
if (key != null)
{
attempt_it = false;
for (WatchEvent event : key.pollEvents()) {
if (event.context().toString().equals("port.txt")) {
Log.w("tildefriends", "Observed file write: " + event.context().toString());
attempt_it = true;
}
}
}
if (attempt_it) {
int port = read_port(port_file_path);
if (port >= 0) {
base_url = "http://127.0.0.1:" + String.valueOf(port) + "/";
activity.runOnUiThread(() -> {
activity.hide_status();
web_view.loadUrl(base_url);
});
break;
} else {
activity.runOnUiThread(() -> {
activity.set_status("Waiting to connect...");
});
}
}
if (key != null && !key.reset()) {
Log.w("tildefriends", "watcher is no longer valid");
break;
}
}
} catch (java.io.IOException e) {
Log.w("tildefriends", "IOException: " + e.toString());
} catch (InterruptedException e) {
Log.w("tildefriends", "InterruptedException: " + e.toString());
}
}
});
thread.start();
set_status("Starting server..."); set_status("Starting server...");
server_thread = new Thread(new Runnable() { server_thread = new Thread(new Runnable() {
@ -392,11 +340,14 @@ public class TildeFriendsActivity extends Activity {
private int read_port(String path) { private int read_port(String path) {
try (BufferedReader reader = new BufferedReader(new FileReader(path))) { try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
return Integer.parseInt(reader.readLine()); String line = reader.readLine();
if (line != null) {
return Integer.parseInt(line);
}
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
e.printStackTrace(); e.printStackTrace();
} catch (java.io.FileNotFoundException e) { } catch (java.io.FileNotFoundException e) {
e.printStackTrace(); Log.w("tildefriends", "Port file does not yet exist.");
} catch (java.io.IOException e) { } catch (java.io.IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -461,6 +412,36 @@ public class TildeFriendsActivity extends Activity {
} }
} }
private void check_port_file(String path) {
int port = read_port(port_file_path);
if (port >= 0) {
base_url = "http://127.0.0.1:" + String.valueOf(port) + "/";
runOnUiThread(() -> {
hide_status();
web_view.loadUrl(base_url);
});
observer = null;
} else {
runOnUiThread(() -> {
set_status("Waiting to connect...");
});
}
}
@SuppressWarnings("deprecation")
private FileObserver make_file_observer(String dir, String path) {
FileObserver file_observer = new FileObserver(dir, FileObserver.ALL_EVENTS) {
@Override
public void onEvent(int event, String file) {
if (observer != null) {
check_port_file(path);
}
}
};
check_port_file(path);
return file_observer;
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void set_database_path() private void set_database_path()
{ {

View File

@ -41,7 +41,7 @@ public class TildeFriendsSandboxService extends Service {
@Override @Override
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) { protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
if (code == START_CALL) { if (code == START_CALL) {
ParcelFileDescriptor pfd = data.readParcelable(ParcelFileDescriptor.class.getClassLoader(), ParcelFileDescriptor.class); ParcelFileDescriptor pfd = read_pfd(data);
if (pfd != null) { if (pfd != null) {
Log.w("tildefriends", "fd is " + pfd.getFd()); Log.w("tildefriends", "fd is " + pfd.getFd());
start_thread(pfd.detachFd()); start_thread(pfd.detachFd());
@ -56,4 +56,9 @@ public class TildeFriendsSandboxService extends Service {
} }
}; };
} }
@SuppressWarnings("deprecation")
static private ParcelFileDescriptor read_pfd(Parcel data) {
return data.readParcelable(ParcelFileDescriptor.class.getClassLoader());
}
} }

View File

@ -69,7 +69,7 @@ static void _tf_ssb_export_scandir(uv_fs_t* req)
int r = uv_fs_unlink(tf_ssb_get_loop(export->ssb), &req, path, NULL); int r = uv_fs_unlink(tf_ssb_get_loop(export->ssb), &req, path, NULL);
if (r) if (r)
{ {
tf_printf("Failed to unlink %s: %s.", path, uv_strerror(r)); tf_printf("Failed to unlink %s: %s.\n", path, uv_strerror(r));
} }
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
tf_free(path); tf_free(path);
@ -199,7 +199,7 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key)
int r = uv_fs_scandir(tf_ssb_get_loop(ssb), &export.req, file_path, 0, _tf_ssb_export_scandir); int r = uv_fs_scandir(tf_ssb_get_loop(ssb), &export.req, file_path, 0, _tf_ssb_export_scandir);
if (r) if (r)
{ {
tf_printf("Failed to scan directory %s: %s.", file_path, uv_strerror(r)); tf_printf("Failed to scan directory %s: %s.\n", file_path, uv_strerror(r));
} }
while (!export.done) while (!export.done)
{ {

View File

@ -155,7 +155,7 @@ static void _tf_ssb_import_recursive_add_files(tf_ssb_t* ssb, uv_loop_t* loop, J
} }
else else
{ {
tf_printf("Failed to scan directory %s: %s.", path, uv_strerror(r)); tf_printf("Failed to scan directory %s: %s.\n", path, uv_strerror(r));
} }
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
} }
@ -260,7 +260,7 @@ void tf_ssb_import(tf_ssb_t* ssb, const char* user, const char* path)
} }
else else
{ {
tf_printf("Failed to scan directory %s: %s.", path, uv_strerror(r)); tf_printf("Failed to scan directory %s: %s.\n", path, uv_strerror(r));
} }
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
} }

View File

@ -1,2 +1,2 @@
#define VERSION_NUMBER "0.0.23" #define VERSION_NUMBER "0.0.24-wip"
#define VERSION_NAME "Me upon my pony on my boat." #define VERSION_NAME "Honey bunches of boats."