Upload files to "/"

This commit is contained in:
mhn
2025-12-05 11:19:17 +00:00
commit 6563056805
4 changed files with 512 additions and 0 deletions

24
README.md Normal file
View File

@@ -0,0 +1,24 @@
# Life Manager
Categorize and manage your life, with calendar and instant lexical search of titles, tags, and the description content of each card.
Select a category, enter info, track info/tasks/projects, timely calendar included.
Built web only version for Netlify deploy and hosting with Nginx etc. try it out: https://lifeman.mhn.lol
Supports backing up and loading data to/from device. *Note clearing cookie or site data will clear the database as it is stored in browser localstorage. So, BACKUP! Your database will persist as long as you don't delete browser cookies/site data. Source is in web folder. Template for JS instant lexical search including title, description, and tags of cards. Included calendar system tied to search, along with the topical tagging system(multi-selected). <-- *nts work on description of this..
## Quick Start🏁
glibc 2.35+ (Ubuntu 22+) binary ready
- ```sh
curl -fsSL https://raw.githubusercontent.com/mrhappynice/lifeman/main/install.sh | bash
```
enter ```lifeman``` folder and run: ```./lifeman``` - sample cards included, delete data.json and restart app for clean db
- windows install just:
```sh
git clone https://github.com/mrhappynice/lifeman.git
```
and download exe, put in lifeman folder. run ```.\lifeman.exe``` in terminal (or double click exe *shrugs* lol) connect http://localhost:3030
Build:
```sh
cargo build --release
```

62
install.sh Normal file
View File

@@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -Eeuo pipefail
BINARY_URL="https://github.com/mrhappynice/lifeman/releases/download/v0.2/lifeman"
JSON_URL="https://github.com/mrhappynice/lifeman/raw/refs/heads/main/data.json"
INSTALL_DIR="lifeman"
BINARY_NAME="lifeman"
JSON_NAME="data.json"
INDEX_NAME="index.html"
SCRIPT_NAME="script.js"
CSS_NAME="style.css"
INDEX_URL="https://github.com/mrhappynice/lifeman/raw/refs/heads/main/static/index.html"
SCRIPT_URL="https://github.com/mrhappynice/lifeman/raw/refs/heads/main/static/script.js"
CSS_URL="https://github.com/mrhappynice/lifeman/raw/refs/heads/main/static/style.css"
# --- helpers ---
have() { command -v "$1" >/dev/null 2>&1; }
download() {
# $1 = url, $2 = output file
if have curl; then
curl -fL --proto '=https' --tlsv1.2 --retry 3 --retry-delay 1 --progress-bar -o "$2" "$1"
elif have wget; then
wget --https-only --tries=3 -O "$2" "$1"
else
echo "Error: need 'curl' or 'wget' to download files." >&2
exit 1
fi
}
# --- work ---
echo "Creating '${INSTALL_DIR}' (if needed)…"
mkdir -p "${INSTALL_DIR}"
cd "${INSTALL_DIR}"
echo "Downloading binary -> ${BINARY_NAME}"
download "${BINARY_URL}" "${BINARY_NAME}"
echo "Downloading json -> ${JSON_NAME}"
download "${JSON_URL}" "${JSON_NAME}"
echo "Making '${BINARY_NAME}' executable…"
chmod +x "${BINARY_NAME}"
echo "Getting UI files.."
mkdir static
cd static
download "${INDEX_URL}" "${INDEX_NAME}"
download "${SCRIPT_URL}" "${SCRIPT_NAME}"
download "${CSS_URL}" "${CSS_NAME}"
echo "Done ✅"
echo
echo "Files installed to: $(pwd)"
echo " - ${BINARY_NAME}"
echo " - ${JSON_NAME}"
echo
echo "Run it with:"
echo " ./$(printf %q "${BINARY_NAME}")"

425
pwa-notes.md Normal file
View File

@@ -0,0 +1,425 @@
---
## Part 1 Turn your current app into a PWA
You already have:
* `index.html`
* `style.css`
* `script.js`
Well add:
* `manifest.webmanifest`
* `sw.js`
* A couple of small changes to `index.html`
Ill assume your app is served from the site root (e.g. `https://mydomain.com/`) and that your icon is a PNG. You can keep everything inside `web/` in your repo; when you deploy, make sure these files end up in the same directory as `index.html`.
---
### 1. Create icons from your existing icon file
Chrome expects at least:
* **192×192** PNG
* **512×512** PNG
If your icon file is large enough (e.g. 1024×1024), generate:
* `icons/icon-192.png`
* `icons/icon-512.png`
(Use something like GIMP, Figma, or an online “PWA icon generator”.)
Folder structure (in `web/`):
```text
web/
index.html
style.css
script.js
sw.js
manifest.webmanifest
icons/
icon-192.png
icon-512.png
```
---
### 2. Add `manifest.webmanifest`
Create `web/manifest.webmanifest`:
```json
{
"name": "Life Manager",
"short_name": "LifeMgr",
"description": "Offline-first life organizer with calendar, tags, and backups.",
"start_url": "/",
"scope": "/",
"display": "standalone",
"background_color": "#0f1014",
"theme_color": "#0f1014",
"orientation": "portrait",
"icons": [
{
"src": "/icons/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
```
> `start_url` and `scope` assume the app is at the root. If you serve from `/life-manager/`, change both to `"/life-manager/"`.
---
### 3. Wire manifest + theme color into `index.html`
Modify your `<head>` in `web/index.html` to include the manifest and theme color.
Right now you have:
```html
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>life-manager</title>
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
</head>
```
Change to:
```html
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>life-manager</title>
<!-- PWA: theme color (matches manifest) -->
<meta name="theme-color" content="#0f1014">
<!-- PWA: manifest -->
<link rel="manifest" href="manifest.webmanifest">
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
</head>
```
---
### 4. Register a service worker from `index.html`
Just before `</body>` you already have:
```html
<script src="script.js"></script>
</body>
</html>
```
Change to:
```html
<script src="script.js"></script>
<!-- PWA: Service worker registration -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.catch(err => {
console.error('SW registration failed', err);
});
});
}
</script>
</body>
</html>
```
> If you host the app under a path (e.g. `/life-manager/`), change the registration path to `'/life-manager/sw.js'`.
---
### 5. Add `sw.js` (service worker)
Create `web/sw.js`:
```js
// sw.js - simple cache-first service worker
const CACHE_NAME = 'lifemgr-cache-v1';
// List everything needed for offline
const ASSETS = [
'/',
'/index.html',
'/style.css',
'/script.js',
'/manifest.webmanifest',
'/icons/icon-192.png',
'/icons/icon-512.png'
];
// Install: cache core assets
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(ASSETS);
})
);
self.skipWaiting();
});
// Activate: cleanup old caches if you bump the version
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((keys) =>
Promise.all(
keys.map((key) => {
if (key !== CACHE_NAME) {
return caches.delete(key);
}
})
)
)
);
self.clients.claim();
});
// Fetch: cache-first strategy
self.addEventListener('fetch', (event) => {
const request = event.request;
// Only handle GET
if (request.method !== 'GET') return;
event.respondWith(
caches.match(request).then((cached) => {
// Serve from cache if available, else network
return (
cached ||
fetch(request).catch(() => {
// Optional: custom offline response for HTML requests
if (request.headers.get('accept')?.includes('text/html')) {
return caches.match('/index.html');
}
})
);
})
);
});
```
> Again, if hosted under a sub-path, prepend `/life-manager` in `ASSETS`.
Now when you deploy over **HTTPS**, Chrome will see:
* a valid manifest,
* a service worker controlling the scope,
* and will treat it as a PWA with install capability.
---
### 6. Deploy and sanity-check
1. Deploy `web/` to somewhere HTTPS (Netlify, Vercel, etc.).
2. Open it in Chrome (Android or desktop).
3. In DevTools → Application → Manifest/Service Workers:
* Confirm manifest is found,
* service worker is active,
* and pages are controlled.
4. On Android Chrome, you should see **“Install app” / “Add to Home screen”** in the menu.
Once this works, youre ready for the **Trusted Web Activity** step.
---
## Part 2 Wrap your PWA in a Trusted Web Activity (TWA) with Bubblewrap
Now you have a real PWA live at (for example):
```text
https://your-domain.com/
```
Well use **Bubblewrap**, which takes your hosted `manifest.webmanifest` and generates an Android project that starts your PWA as a TWA.
### 1. Prereqs checklist
You need:
* Node.js (v14+)
* Java JDK
* Android SDK
* Your PWA served via **HTTPS** with:
* manifest,
* service worker,
* and working offline (which we just did).
And of course, a **Google Play developer account** for publishing later.
---
### 2. Install Bubblewrap CLI
```bash
npm install -g @bubblewrap/cli
bubblewrap --version
```
(Just to confirm its installed.)
---
### 3. Initialize a Bubblewrap project from your manifest
Pick a new folder for the Android project:
```bash
mkdir life-manager-twa
cd life-manager-twa
```
Run the init command, pointing to your **hosted** manifest:
```bash
bubblewrap init --manifest https://your-domain.com/manifest.webmanifest
```
Bubblewrap will:
* Download the web manifest.
* Ask you about:
* **Package ID** (e.g. `com.yourdomain.lifemanager`)
* **App name** (can reuse `"Life Manager"`)
* **Colors, icons, orientation** (it can reuse values from the manifest)
* **Signing key** (create a new keystore or use an existing one)
It will generate:
* An Android project (Gradle, Java/Kotlin code that opens your URL as a TWA).
* A `twa-manifest.json` with config about your app.
* An `assetlinks.json` file template for your website.
---
### 4. Build the APK/App Bundle
Inside that new project folder:
```bash
bubblewrap build
```
This compiles the Android project and outputs a release build (APK/App Bundle).
You can also install directly on a connected device:
```bash
bubblewrap install
```
At this stage, when you open the app on the device:
* It will usually open as a **Custom Tab** (with a little browser UI) until we set up the trust link (Digital Asset Links).
---
### 5. Set up Digital Asset Links (`assetlinks.json`)
To get true **Trusted Web Activity** (full screen, no browser bar), Android needs to verify that:
* The app signing key
* And your websites domain
belong to the same owner, via **Digital Asset Links**.
Bubblewrap will give you an `assetlinks.json` snippet. If you need a template, it looks like this:
```json
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.yourdomain.lifemanager",
"sha256_cert_fingerprints": [
"AA:BB:CC:DD:EE:FF:..."
]
}
}
]
```
* Replace `com.yourdomain.lifemanager` with your actual package ID.
* Replace the fingerprint with the SHA-256 of the keystore you **actually sign the Play build with** (Bubblewrap/Android Studio docs show how to get this).
Host this file at:
```text
https://your-domain.com/.well-known/assetlinks.json
```
Once this is accessible and valid:
* Opening your app on device will show your PWA **full-screen** as a Trusted Web Activity, not a normal Chrome tab.
---
### 6. Open in Android Studio (optional but recommended)
You can open the generated Android project in Android Studio for:
* Changing app name, icon, version code, etc.
* Building signed App Bundles for the Play Store.
* Running on emulators.
Bubblewraps `build` and `install` commands already use Gradle under the hood, so this is optional, but very handy for Play Store upload.
---
### 7. Upload to Google Play
Once:
* PWA runs well over HTTPS.
* Asset Links are configured and verified.
* The app works as full-screen TWA on a device.
Then:
1. In the **Google Play Console**, create a new app.
2. Upload the signed **App Bundle/APK** from your Bubblewrap/Android Studio build.
3. Fill in listing details (screenshots, description, etc.).
4. Roll out a test track or production release.
---

1
rebuild.sh Normal file
View File

@@ -0,0 +1 @@
cargo clean && cargo build --release