Compare commits
	
		
			5 Commits
		
	
	
		
			v0.0.17
			...
			4b7261fa20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4b7261fa20 | |||
| 88ee0aa6f0 | |||
| 392206c19e | |||
| 
						
						
							
						
						f9e95e5733
	
				 | 
					
					
						|||
| 
						
						
							
						
						1444c945de
	
				 | 
					
					
						
							
								
								
									
										44
									
								
								GNUmakefile
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								GNUmakefile
									
									
									
									
									
								
							@@ -4,7 +4,7 @@ MAKEFLAGS += --warn-undefined-variables
 | 
			
		||||
MAKEFLAGS += --no-builtin-rules
 | 
			
		||||
 | 
			
		||||
VERSION_CODE := 17
 | 
			
		||||
VERSION_NUMBER := 0.0.17
 | 
			
		||||
VERSION_NUMBER := 0.0.17-wip
 | 
			
		||||
VERSION_NAME := Please enjoy responsibly.
 | 
			
		||||
 | 
			
		||||
SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3450200.zip
 | 
			
		||||
@@ -17,6 +17,18 @@ UNAME_M := $(shell uname -m)
 | 
			
		||||
 | 
			
		||||
ANDROID_SDK ?= ~/Android/Sdk
 | 
			
		||||
 | 
			
		||||
ifeq ($(UNAME_M),x86_64)
 | 
			
		||||
ifneq ($(UNAME_S),Haiku)
 | 
			
		||||
debug: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
 | 
			
		||||
debug: LDFLAGS += -fsanitize=address -fsanitize=undefined
 | 
			
		||||
endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(UNAME_M),aarch64)
 | 
			
		||||
debug: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
 | 
			
		||||
debug: LDFLAGS += -fsanitize=address -fsanitize=undefined
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(UNAME_S),Darwin)
 | 
			
		||||
BUILD_TYPES := macosdebug macosrelease iosdebug iosrelease iossimdebug iossimrelease
 | 
			
		||||
else ifeq ($(UNAME_S),Linux)
 | 
			
		||||
@@ -210,18 +222,6 @@ $(IOS_TARGETS): LDFLAGS += -Ldeps/openssl/ios/ios64-xcrun/usr/local/lib
 | 
			
		||||
$(IOSSIM_TARGETS): CFLAGS += -Ideps/openssl/ios/iossimulator-xcrun/usr/local/include
 | 
			
		||||
$(IOSSIM_TARGETS): LDFLAGS += -Ldeps/openssl/ios/iossimulator-xcrun/usr/local/lib
 | 
			
		||||
 | 
			
		||||
ifeq ($(UNAME_M),x86_64)
 | 
			
		||||
ifneq ($(UNAME_S),Haiku)
 | 
			
		||||
out/debug/tildefriends: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
 | 
			
		||||
out/debug/tildefriends: LDFLAGS += -fsanitize=address -fsanitize=undefined
 | 
			
		||||
endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(UNAME_M),aarch64)
 | 
			
		||||
out/debug/tildefriends: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
 | 
			
		||||
out/debug/tildefriends: LDFLAGS += -fsanitize=address -fsanitize=undefined
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
get_objs = \
 | 
			
		||||
	$(foreach build_type,$(BUILD_TYPES),$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)))))) \
 | 
			
		||||
	$(foreach build_type,debug release,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
 | 
			
		||||
@@ -578,7 +578,7 @@ $(MINIUNZIP_OBJS): CFLAGS += \
 | 
			
		||||
LDFLAGS += \
 | 
			
		||||
	-pthread \
 | 
			
		||||
	-lm
 | 
			
		||||
$(LINUX_TARGETS) $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
 | 
			
		||||
debug release $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
 | 
			
		||||
	-lssl \
 | 
			
		||||
	-lcrypto
 | 
			
		||||
ifneq ($(UNAME_S),Haiku)
 | 
			
		||||
@@ -728,7 +728,7 @@ out/apk/TildeFriends-arm-%.unsigned.apk:
 | 
			
		||||
	@cp out/apk/res.apk $@.zip
 | 
			
		||||
	@cp out/apk/classes.dex out/apk-arm-$(BUILD_TYPE)/
 | 
			
		||||
	@cd out/apk-arm-$(BUILD_TYPE) && zip -u ../../$@.zip -q -9 -r . && cd ../../
 | 
			
		||||
	@zip -u $@.zip -q -9 $(RAW_FILES)
 | 
			
		||||
	@zip -u $@.zip -q $(RAW_FILES)
 | 
			
		||||
	@$(ANDROID_BUILD_TOOLS)/zipalign -f 4 $@.zip $@
 | 
			
		||||
 | 
			
		||||
out/apk/TildeFriends-x86-%.unsigned.apk:
 | 
			
		||||
@@ -741,7 +741,7 @@ out/apk/TildeFriends-x86-%.unsigned.apk:
 | 
			
		||||
	@cp out/apk/res.apk $@.zip
 | 
			
		||||
	@cp out/apk/classes.dex out/apk-x86-$(BUILD_TYPE)/
 | 
			
		||||
	@cd out/apk-x86-$(BUILD_TYPE) && zip -u ../../$@.zip -q -9 -r . && cd ../../
 | 
			
		||||
	@zip -u $@.zip -q -9 $(RAW_FILES)
 | 
			
		||||
	@zip -u $@.zip -q $(RAW_FILES)
 | 
			
		||||
	@$(ANDROID_BUILD_TOOLS)/zipalign -f 4 $@.zip $@
 | 
			
		||||
 | 
			
		||||
out/%.apk: out/apk/%.unsigned.apk
 | 
			
		||||
@@ -769,10 +769,10 @@ out/%.app/tildefriends.png: src/ios/tildefriends.png
 | 
			
		||||
	@mkdir -p $(dir $@)
 | 
			
		||||
	@cp -v $< $@
 | 
			
		||||
 | 
			
		||||
out/data.zip: $(RAW_FILES)
 | 
			
		||||
out/%/data.zip: $(RAW_FILES)
 | 
			
		||||
	@zip -u $@ -q -9 $(RAW_FILES)
 | 
			
		||||
 | 
			
		||||
out/tildefriends-%.app/tildefriends: out/%/tildefriends out/tildefriends-%.app/Info.plist out/tildefriends-%.app/tildefriends.png out/data.zip
 | 
			
		||||
out/tildefriends-%.app/tildefriends: out/%/tildefriends out/tildefriends-%.app/Info.plist out/tildefriends-%.app/tildefriends.png out/tildefriends-%.app/data.zip
 | 
			
		||||
	@mkdir -p $(dir $@)
 | 
			
		||||
	@cp -v $< $@
 | 
			
		||||
ifeq ($(HAVE_LINUX_IOS),1)
 | 
			
		||||
@@ -787,12 +787,6 @@ out/tildefriends-%.ipa: out/tildefriends-ios%.app/tildefriends
 | 
			
		||||
	@cd $@.tmp/ && zip -u ../../$@ -q -9 -r ./
 | 
			
		||||
	@rm -rf $@.tmp/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
out/%/tildefriends.standalone: out/%/tildefriends out/data.zip
 | 
			
		||||
	@echo "[standalone] $@"
 | 
			
		||||
	@cat $< out/data.zip > $@
 | 
			
		||||
	@chmod +x $@
 | 
			
		||||
 | 
			
		||||
iossimdebug-app: out/tildefriends-iossimdebug.app/tildefriends
 | 
			
		||||
iossimrelease-app: out/tildefriends-iossimrelease.app/tildefriends
 | 
			
		||||
iosdebug-app: out/tildefriends-iosdebug.app/tildefriends
 | 
			
		||||
@@ -857,7 +851,7 @@ dist: release-apk iosrelease-ipa
 | 
			
		||||
	@echo [archive] dist/tildefriends-$(VERSION_NUMBER).tar.xz
 | 
			
		||||
	@rm -rf out/tildefriends-$(VERSION_NUMBER)
 | 
			
		||||
	@mkdir -p dist/ out/tildefriends-$(VERSION_NUMBER)
 | 
			
		||||
	@git archive HEAD | tar -x -C out/tildefriends-$(VERSION_NUMBER)
 | 
			
		||||
	@git archive main | tar -x -C out/tildefriends-$(VERSION_NUMBER)
 | 
			
		||||
	@tar \
 | 
			
		||||
		--exclude=apps/welcome* \
 | 
			
		||||
		--exclude=deps/libbacktrace/Isaac.Newton-Opticks.txt \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								apps/user_settings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								apps/user_settings.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
{
 | 
			
		||||
  "type": "tildefriends-app",
 | 
			
		||||
  "emoji": "⚙️"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								apps/user_settings/app.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								apps/user_settings/app.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
import * as tfrpc from '/tfrpc.js';
 | 
			
		||||
 | 
			
		||||
tfrpc.register(async function getIdentities() {
 | 
			
		||||
	return ssb.getIdentities();
 | 
			
		||||
});
 | 
			
		||||
tfrpc.register(async function getPrivateKey(id) {
 | 
			
		||||
	return bip39Words(await ssb.getPrivateKey(id));
 | 
			
		||||
});
 | 
			
		||||
tfrpc.register(async function getThemes() {
 | 
			
		||||
	// TODO
 | 
			
		||||
	return ['solarized', 'gruvbox', 'light'];
 | 
			
		||||
});
 | 
			
		||||
tfrpc.register(async function setTheme() {
 | 
			
		||||
	// TODO
 | 
			
		||||
	console.warn("setTheme called - not implemented")
 | 
			
		||||
	return null;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
async function main() {
 | 
			
		||||
	// Get body.html
 | 
			
		||||
	const body = utf8Decode(await getFile('body.html'));
 | 
			
		||||
 | 
			
		||||
	// Build the document
 | 
			
		||||
	const document = `
 | 
			
		||||
	<!DOCTYPE html>
 | 
			
		||||
	<html>
 | 
			
		||||
		<head>
 | 
			
		||||
			<link rel="stylesheet" href="/static/tildefriends-latest.css"/>
 | 
			
		||||
			<link rel="stylesheet" href="style.css"/>
 | 
			
		||||
			<script src="script.js" type="module"></script>
 | 
			
		||||
			<script src="tf-theme-picker.js" type="module"></script>
 | 
			
		||||
			<script src="tf-password-form.js" type="module"></script>
 | 
			
		||||
			<script src="tf-delete-account-btn.js" type="module"></script>
 | 
			
		||||
			<script src="tf-identity-manager.js" type="module"></script>
 | 
			
		||||
		</head>
 | 
			
		||||
 | 
			
		||||
		<body class="flex-column">
 | 
			
		||||
			${body}
 | 
			
		||||
		</body>
 | 
			
		||||
	</html>`;
 | 
			
		||||
 | 
			
		||||
	// Send it to the browser
 | 
			
		||||
	app.setDocument(document);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
main();
 | 
			
		||||
							
								
								
									
										20
									
								
								apps/user_settings/body.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								apps/user_settings/body.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
<h1>Your settings</h1>
 | 
			
		||||
 | 
			
		||||
<div class="box flex-column">
 | 
			
		||||
	<h2>Appearance</h2>
 | 
			
		||||
 | 
			
		||||
	<tf-theme-picker></tf-theme-picker>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<div class="box flex-column">
 | 
			
		||||
	<h2>Danger Zone</h2>
 | 
			
		||||
 | 
			
		||||
	<h3>Change my password</h3>
 | 
			
		||||
	<tf-password-form></tf-password-form>
 | 
			
		||||
 | 
			
		||||
	<h3>Manage your identities</h3>
 | 
			
		||||
	<tf-identity-manager></tf-identity-manager>
 | 
			
		||||
 | 
			
		||||
	<h3>Delete your account</h3>
 | 
			
		||||
	<tf-delete-account-btn></tf-delete-account-btn>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										120
									
								
								apps/user_settings/lit-all.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								apps/user_settings/lit-all.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								apps/user_settings/lit-all.min.js.map
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								apps/user_settings/lit-all.min.js.map
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								apps/user_settings/script.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								apps/user_settings/script.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
/* */
 | 
			
		||||
							
								
								
									
										1
									
								
								apps/user_settings/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								apps/user_settings/style.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
/* */
 | 
			
		||||
							
								
								
									
										36
									
								
								apps/user_settings/tf-delete-account-btn.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								apps/user_settings/tf-delete-account-btn.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
import {LitElement, html} from './lit-all.min.js';
 | 
			
		||||
import * as tfrpc from '/static/tfrpc.js';
 | 
			
		||||
 | 
			
		||||
class TfDeleteAccountButtonElement extends LitElement {
 | 
			
		||||
	static get properties() {
 | 
			
		||||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	deleteAccount() {
 | 
			
		||||
		const res = confirm(
 | 
			
		||||
			'Are you really sure you want to delete your account ?'
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		if (!res) return;
 | 
			
		||||
 | 
			
		||||
		console.warn('TODO');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	render() {
 | 
			
		||||
		return html`
 | 
			
		||||
			<link rel="stylesheet" href="/static/tildefriends-latest.css"/>
 | 
			
		||||
 | 
			
		||||
			<span>This action is irreversible !</span>
 | 
			
		||||
 | 
			
		||||
			<button class="red" @click=${this.deleteAccount}>
 | 
			
		||||
				[Not implemented] Delete my Tilde Friends account
 | 
			
		||||
			</button>
 | 
			
		||||
		`;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
customElements.define('tf-delete-account-btn', TfDeleteAccountButtonElement);
 | 
			
		||||
							
								
								
									
										61
									
								
								apps/user_settings/tf-identity-manager.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								apps/user_settings/tf-identity-manager.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
import {LitElement, html} from './lit-all.min.js';
 | 
			
		||||
import * as tfrpc from '/static/tfrpc.js';
 | 
			
		||||
 | 
			
		||||
class TfIdentityManagerElement extends LitElement {
 | 
			
		||||
	static get properties() {
 | 
			
		||||
		return {
 | 
			
		||||
			ids: {type: Array},
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super();
 | 
			
		||||
		this.ids = [];
 | 
			
		||||
		this.load();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	async load() {
 | 
			
		||||
		this.ids = await tfrpc.rpc.getIdentities();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	async exportIdentity(id) {
 | 
			
		||||
		alert('Your private key is:\n' + (await tfrpc.rpc.getPrivateKey(id)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	render() {
 | 
			
		||||
		return html`
 | 
			
		||||
			<link rel="stylesheet" href="/static/tildefriends-latest.css"/>
 | 
			
		||||
			<style>
 | 
			
		||||
				.id-span {
 | 
			
		||||
					font-family: monospace;
 | 
			
		||||
					margin-left: 8px;
 | 
			
		||||
				}
 | 
			
		||||
			</style>
 | 
			
		||||
 | 
			
		||||
			<h4>Create a new identity</h4>
 | 
			
		||||
			<button id="create-id" class="btn-green">[Not implemented] Create Identity</button>
 | 
			
		||||
 | 
			
		||||
			<h4>Import an SSB Identity from 12 BIP39 English Words</h4>
 | 
			
		||||
			<textarea id="add-id" style="width: 100%" rows="4"></textarea>
 | 
			
		||||
			<button class="green">[Not implemented] Import Identity</button>
 | 
			
		||||
 | 
			
		||||
			<h4>Warning !</h4>
 | 
			
		||||
			<strong>Anybody that has access to your private key can gain total access over your account.</strong>
 | 
			
		||||
			<br><br>
 | 
			
		||||
			Tilde Friends' contributors will never ask you for your private key !
 | 
			
		||||
 | 
			
		||||
			<ul>
 | 
			
		||||
			${this.ids.map(
 | 
			
		||||
				(id) =>
 | 
			
		||||
					html`
 | 
			
		||||
				<li>
 | 
			
		||||
					<button class="blue" @click=${() => this.exportIdentity(id)}>Export Identity</button>
 | 
			
		||||
					<button class="red">[Not implemented] Delete Identity</button>
 | 
			
		||||
					<span class="id-span">${id}</span>
 | 
			
		||||
				</li>`
 | 
			
		||||
			)}
 | 
			
		||||
			</ul>`;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
customElements.define('tf-identity-manager', TfIdentityManagerElement);
 | 
			
		||||
							
								
								
									
										68
									
								
								apps/user_settings/tf-password-form.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								apps/user_settings/tf-password-form.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
import {LitElement, html} from './lit-all.min.js';
 | 
			
		||||
import * as tfrpc from '/static/tfrpc.js';
 | 
			
		||||
 | 
			
		||||
class TfPasswordFormElement extends LitElement {
 | 
			
		||||
	static get properties() {
 | 
			
		||||
		return {
 | 
			
		||||
			//selected: {type: String},
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Checks a password against different requirements
 | 
			
		||||
	 * @param {string} password the password to validate
 | 
			
		||||
	 * @returns
 | 
			
		||||
	 */
 | 
			
		||||
	validatePassword(password) {
 | 
			
		||||
		// TODO(tasiaiso)
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	submitPassword() {
 | 
			
		||||
		const currentPwd = this.shadowRoot.getElementById('current').value;
 | 
			
		||||
		const newPwd = this.shadowRoot.getElementById('new').value;
 | 
			
		||||
		const repeatPwd = this.shadowRoot.getElementById('Repeat').value;
 | 
			
		||||
 | 
			
		||||
		if (!(newPwd === repeatPwd)) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// TODO
 | 
			
		||||
		// tfrpc.changePassword()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	render() {
 | 
			
		||||
		return html`
 | 
			
		||||
			<link rel="stylesheet" href="/static/tildefriends-latest.css"/>
 | 
			
		||||
 | 
			
		||||
			<style>
 | 
			
		||||
				.grid {
 | 
			
		||||
					display: grid;
 | 
			
		||||
					grid-template-columns: auto auto;
 | 
			
		||||
				}
 | 
			
		||||
			</style>
 | 
			
		||||
 | 
			
		||||
			<div class="grid">
 | 
			
		||||
				<label for="current">Current password:</label>
 | 
			
		||||
				<input type="password" id="current" name="current" autocomplete="current-password" />
 | 
			
		||||
 | 
			
		||||
				<label for="new">Enter new password:</label>
 | 
			
		||||
				<input type="password" id="new" name="new" autocomplete="new-password" />
 | 
			
		||||
 | 
			
		||||
				<label for="repeat">Repeat new password:</label>
 | 
			
		||||
				<input type="password" id="repeat" name="repeat" autocomplete="new-password" />
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<button @click=${this.submitPassword} class="red">
 | 
			
		||||
				[Not implemented] Change my password
 | 
			
		||||
			</button>
 | 
			
		||||
 | 
			
		||||
		`;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
customElements.define('tf-password-form', TfPasswordFormElement);
 | 
			
		||||
							
								
								
									
										40
									
								
								apps/user_settings/tf-theme-picker.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								apps/user_settings/tf-theme-picker.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
import {LitElement, html} from './lit-all.min.js';
 | 
			
		||||
import * as tfrpc from '/static/tfrpc.js';
 | 
			
		||||
 | 
			
		||||
class TfThemePickerElement extends LitElement {
 | 
			
		||||
	static get properties() {
 | 
			
		||||
		return {
 | 
			
		||||
			selected: {type: String},
 | 
			
		||||
			themes: {type: Array},
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super();
 | 
			
		||||
		this.load();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	async load() {
 | 
			
		||||
		this.themes = await tfrpc.rpc.getThemes();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	changed(event) {
 | 
			
		||||
		this.selected = event.srcElement.value;
 | 
			
		||||
		console.log('selected theme', this.selected);
 | 
			
		||||
		// TODO
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	render() {
 | 
			
		||||
		return html`
 | 
			
		||||
			<link rel="stylesheet" href="/static/tildefriends-latest.css"/>
 | 
			
		||||
 | 
			
		||||
			<label for="theme">[Not implemented] Choose your theme:</label>
 | 
			
		||||
 | 
			
		||||
			<select name="theme" ?hidden=${!this.themes?.length} @change=${this.changed}>
 | 
			
		||||
				${(this.themes ?? []).map((id) => html`<option value=${id}>${id}</option>`)}
 | 
			
		||||
			</select>
 | 
			
		||||
		`;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
customElements.define('tf-theme-picker', TfThemePickerElement);
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								bleh.tar.xz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								bleh.tar.xz
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										113
									
								
								core/tildefriends-v1.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								core/tildefriends-v1.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Tilde Friends core stylesheet
 | 
			
		||||
 *
 | 
			
		||||
 * This Software is an external library that is part of
 | 
			
		||||
 * Tilde Friends and is shared under the MIT license.
 | 
			
		||||
 *
 | 
			
		||||
 * Inject this file in your app at tildefriends.css
 | 
			
		||||
 * and use this tag to import it:
 | 
			
		||||
 * <link rel="stylesheet" href="/static/tildefriends-v1.css"/>
 | 
			
		||||
 *
 | 
			
		||||
 * v1.0.0 / 2024 M03 21
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
	color: white;
 | 
			
		||||
	font-family: sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
button,
 | 
			
		||||
.button,
 | 
			
		||||
input[type=button],
 | 
			
		||||
input[type=submit],
 | 
			
		||||
select {
 | 
			
		||||
	border: none;
 | 
			
		||||
	border-radius: 8px;
 | 
			
		||||
	padding: 8px 12px;
 | 
			
		||||
	text-align: center;
 | 
			
		||||
	text-decoration: none;
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
	margin: 4px;
 | 
			
		||||
 | 
			
		||||
	&.red {
 | 
			
		||||
		background-color: #bd1e24;
 | 
			
		||||
		color: white;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	&.green {
 | 
			
		||||
		background-color: #18922d;
 | 
			
		||||
		color: white;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	&.blue {
 | 
			
		||||
		background-color: #0067a7;
 | 
			
		||||
		color: white;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	&.yellow {
 | 
			
		||||
		background-color: #ee9600;
 | 
			
		||||
		color: black;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	&:hover {
 | 
			
		||||
		filter: brightness(0.75);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a:link {
 | 
			
		||||
	color: #268bd2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a:visited {
 | 
			
		||||
	color: #6c71c4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a:hover {
 | 
			
		||||
	color: #859900;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a:active {
 | 
			
		||||
	color: #2aa198;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table {
 | 
			
		||||
	border-collapse: collapse;
 | 
			
		||||
	width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
td, th {
 | 
			
		||||
	border: 1px solid #ffffff40;
 | 
			
		||||
	text-align: left;
 | 
			
		||||
	padding: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tr:nth-child(even) {
 | 
			
		||||
	background-color: #ffffff20;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.flex {
 | 
			
		||||
	display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.flex-column {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: column;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.flex-row {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: row;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.inline-flex-row {
 | 
			
		||||
	display: inline-flex;
 | 
			
		||||
	flex-direction: row;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.box {
 | 
			
		||||
	background-color: #00000020;
 | 
			
		||||
	border: 1px solid grey;
 | 
			
		||||
	border-radius: 8px;
 | 
			
		||||
	padding: 16px;
 | 
			
		||||
	margin: 4px;
 | 
			
		||||
}
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
	package="com.unprompted.tildefriends"
 | 
			
		||||
	android:versionCode="17"
 | 
			
		||||
	android:versionName="0.0.17">
 | 
			
		||||
	android:versionName="0.0.17-wip">
 | 
			
		||||
	<uses-sdk android:minSdkVersion="24" android:targetSdkVersion="34"/>
 | 
			
		||||
	<uses-permission android:name="android.permission.INTERNET"/>
 | 
			
		||||
	<application
 | 
			
		||||
 
 | 
			
		||||
@@ -316,9 +316,7 @@ static void _file_read_file_zip_after_work(uv_work_t* work, int status)
 | 
			
		||||
	tf_trace_begin(trace, "file_read_zip_after_work");
 | 
			
		||||
	if (data->result >= 0)
 | 
			
		||||
	{
 | 
			
		||||
		JSValue array = tf_util_new_uint8_array(data->context, data->buffer, data->result);
 | 
			
		||||
		tf_task_resolve_promise(data->task, data->promise, array);
 | 
			
		||||
		JS_FreeValue(data->context, array);
 | 
			
		||||
		tf_task_resolve_promise(data->task, data->promise, tf_util_new_uint8_array(data->context, data->buffer, data->result));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								src/http.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								src/http.c
									
									
									
									
									
								
							@@ -161,11 +161,10 @@ static void _http_request_destroy(tf_http_request_t* request)
 | 
			
		||||
	tf_http_close_callback* on_close = request->on_close;
 | 
			
		||||
	if (on_close)
 | 
			
		||||
	{
 | 
			
		||||
		tf_trace_t* trace = request->http->trace;
 | 
			
		||||
		request->on_close = NULL;
 | 
			
		||||
		tf_trace_begin(trace, request->connection && request->connection->trace_name ? request->connection->trace_name : "websocket");
 | 
			
		||||
		tf_trace_begin(request->http->trace, request->connection && request->connection->trace_name ? request->connection->trace_name : "websocket");
 | 
			
		||||
		on_close(request);
 | 
			
		||||
		tf_trace_end(trace);
 | 
			
		||||
		tf_trace_end(request->http->trace);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -175,9 +174,12 @@ static void _http_connection_destroy(tf_http_connection_t* connection, const cha
 | 
			
		||||
 | 
			
		||||
	if (connection->request)
 | 
			
		||||
	{
 | 
			
		||||
		tf_http_request_t* request = connection->request;
 | 
			
		||||
		_http_request_destroy(connection->request);
 | 
			
		||||
		if (connection->request && connection->request->ref_count == 0)
 | 
			
		||||
		{
 | 
			
		||||
			tf_free(connection->request);
 | 
			
		||||
		}
 | 
			
		||||
		connection->request = NULL;
 | 
			
		||||
		_http_request_destroy(request);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (connection->tcp.data && !uv_is_closing((uv_handle_t*)&connection->tcp))
 | 
			
		||||
@@ -381,19 +383,11 @@ static void _http_add_body_bytes(tf_http_connection_t* connection, const void* d
 | 
			
		||||
			};
 | 
			
		||||
			connection->request = request;
 | 
			
		||||
 | 
			
		||||
			if (!connection->http->is_shutting_down)
 | 
			
		||||
			{
 | 
			
		||||
				tf_http_request_ref(request);
 | 
			
		||||
				tf_trace_begin(connection->http->trace, connection->trace_name ? connection->trace_name : "http");
 | 
			
		||||
				connection->callback(request);
 | 
			
		||||
				tf_trace_end(connection->http->trace);
 | 
			
		||||
				tf_http_request_unref(request);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				const char* k_payload = tf_http_status_text(503);
 | 
			
		||||
				tf_http_respond(request, 503, NULL, 0, k_payload, strlen(k_payload));
 | 
			
		||||
			}
 | 
			
		||||
			tf_http_request_ref(request);
 | 
			
		||||
			tf_trace_begin(connection->http->trace, connection->trace_name ? connection->trace_name : "http");
 | 
			
		||||
			connection->callback(request);
 | 
			
		||||
			tf_trace_end(connection->http->trace);
 | 
			
		||||
			tf_http_request_unref(request);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -792,8 +786,6 @@ const char* tf_http_status_text(int status)
 | 
			
		||||
		return "File not found";
 | 
			
		||||
	case 500:
 | 
			
		||||
		return "Internal server error";
 | 
			
		||||
	case 503:
 | 
			
		||||
		return "Service Unavailable";
 | 
			
		||||
	default:
 | 
			
		||||
		return "Unknown";
 | 
			
		||||
	}
 | 
			
		||||
@@ -973,11 +965,11 @@ void tf_http_request_unref(tf_http_request_t* request)
 | 
			
		||||
	tf_http_connection_t* connection = request->connection;
 | 
			
		||||
	if (--request->ref_count == 0)
 | 
			
		||||
	{
 | 
			
		||||
		_http_request_destroy(request);
 | 
			
		||||
		if (connection)
 | 
			
		||||
		{
 | 
			
		||||
			connection->request = NULL;
 | 
			
		||||
		}
 | 
			
		||||
		_http_request_destroy(request);
 | 
			
		||||
		tf_free(request);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -644,6 +644,7 @@ static void _httpd_endpoint_static(tf_http_request_t* request)
 | 
			
		||||
		"style.css",
 | 
			
		||||
		"tfrpc.js",
 | 
			
		||||
		"w3.css",
 | 
			
		||||
		"tildefriends-v1.css"
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const char* k_map[][2] = {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@
 | 
			
		||||
 | 
			
		||||
#include "backtrace.h"
 | 
			
		||||
#include "sqlite3.h"
 | 
			
		||||
#include "unzip.h"
 | 
			
		||||
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -417,14 +416,6 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
 | 
			
		||||
	};
 | 
			
		||||
	bool show_usage = false;
 | 
			
		||||
 | 
			
		||||
	/* Check if the executable has data attached. */
 | 
			
		||||
	unzFile zip = unzOpen(file);
 | 
			
		||||
	if (zip)
 | 
			
		||||
	{
 | 
			
		||||
		args.zip = file;
 | 
			
		||||
		unzClose(zip);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (!show_usage)
 | 
			
		||||
	{
 | 
			
		||||
		static const struct option k_options[] = {
 | 
			
		||||
 
 | 
			
		||||
@@ -1939,11 +1939,6 @@ void tf_task_destroy(tf_task_t* task)
 | 
			
		||||
	tf_free(task->_promise_stacks);
 | 
			
		||||
	tf_free((void*)task->_path);
 | 
			
		||||
	bool was_trusted = task->_trusted;
 | 
			
		||||
	if (task->_zip)
 | 
			
		||||
	{
 | 
			
		||||
		unzClose(task->_zip);
 | 
			
		||||
		task->_zip = NULL;
 | 
			
		||||
	}
 | 
			
		||||
	tf_free(task);
 | 
			
		||||
	if (was_trusted)
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,2 +1,2 @@
 | 
			
		||||
#define VERSION_NUMBER "0.0.17"
 | 
			
		||||
#define VERSION_NUMBER "0.0.17-wip"
 | 
			
		||||
#define VERSION_NAME "Please enjoy responsibly."
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user