feedback-free.openapps.xyz

Source

This app’s code and revision history are public. Download a copy or explore the files below.

Public
The app’s code and revision history are public.
Owned app · rev 4a4c54cd95c6
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 54b9c9d7fdc2b68029ce2e57
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
← All files
src/lib/mine.ts
// What this browser remembers: boards it manages (with their admin keys), boards it opened, and the name
// it posts under. Lives only in this browser; the admin link carries a key to another device.
export interface MyBoard { id: string; title: string; key?: string; at: number }

const BOARDS = "feedback:boards";
const VISITED = "feedback:visited";
const NAME = "feedback:name";

function read<T>(key: string, fallback: T): T {
  try {
    const v = JSON.parse(localStorage.getItem(key) || "null");
    return v ?? fallback;
  } catch {
    return fallback;
  }
}

export function myBoards(): MyBoard[] {
  const list = read<MyBoard[]>(BOARDS, []);
  return Array.isArray(list) ? list.filter((b) => b && typeof b.id === "string" && b.key) : [];
}

export function rememberBoard(board: Partial<MyBoard> & { id: string }) {
  const list = read<MyBoard[]>(BOARDS, []).filter((b) => b && typeof b.id === "string");
  const prev = list.find((b) => b.id === board.id);
  const next = { title: "", at: Date.now(), ...prev, ...board };
  localStorage.setItem(BOARDS, JSON.stringify([next, ...list.filter((b) => b.id !== board.id)].slice(0, 200)));
}

export function forgetBoard(id: string) {
  localStorage.setItem(BOARDS, JSON.stringify(read<MyBoard[]>(BOARDS, []).filter((b) => b.id !== id)));
}

export const adminKey = (id: string) => myBoards().find((b) => b.id === id)?.key;

/** Boards this browser opened, newest first, so votes can come along when the person signs in. */
export function visitedBoards(): string[] {
  const list = read<string[]>(VISITED, []);
  return Array.isArray(list) ? list.filter((x) => typeof x === "string") : [];
}

export function rememberVisit(id: string) {
  localStorage.setItem(VISITED, JSON.stringify([id, ...visitedBoards().filter((x) => x !== id)].slice(0, 50)));
}

export const savedName = () => localStorage.getItem(NAME) || "";
export const saveName = (name: string) => localStorage.setItem(NAME, name.trim());

Change history

Point store links to openapps.free
4a4c54cd95 · 18 hours ago
Release with preview
1d0728818d · 19 hours ago
Retry release
1abc843b3f · 19 hours ago
Bind app agent address in policy
00eb15f50d · 19 hours ago
Use OpenApps service URLs and add contribution strip
347a7b8ca0 · 19 hours ago
Bounded source sync
a0aaceae63 · 1 day ago
Bounded source sync
3125b8113f · 1 day ago
Bounded source sync
882a76ba95 · 1 day ago
Bounded source sync
852d9782ee · 1 day ago
Bounded source sync
a8ee705109 · 1 day ago