lingo-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 8af89d2cc9f8
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 7efc97d0dde0b2a3e729ccf9
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/Start.tsx
// The language picker in the landing hero: one tap starts the first lesson, no sign-up.
// Returning learners see where they left off.
import { LANGUAGES } from "../functions/lib/course";
import { useLearner, course as courseOf, streak } from "./lib/progress";
import { Arrow, Flame } from "./icons";

export function Start() {
  const s = useLearner();
  const current = LANGUAGES.find((l) => l.id === s.course);
  return (
    <div className="start card">
      {current && (
        <a className="start-continue" href={`/learn/${current.id}`} data-app>
          <span>
            <strong>Continue {current.name}</strong>
            <span className="muted small">{Object.keys(courseOf(s, current.id).done).length} lessons done{streak(s) ? ` · ` : ""}{streak(s) ? <><Flame size={14} className="gold inline-icon" /> {streak(s)} day streak</> : null}</span>
          </span>
          <Arrow />
        </a>
      )}
      <p className="start-label">{current ? "Or pick another language" : "I want to learn"}</p>
      <ul className="start-list">
        {LANGUAGES.map((l) => {
          const begun = Object.keys(courseOf(s, l.id).done).length > 0;
          return (
            <li key={l.id}>
              <a className="start-lang" href={begun ? `/learn/${l.id}` : `/learn/${l.id}/lesson/1/1`} data-app>
                <span className="course-code" aria-hidden="true">{l.id.toUpperCase()}</span>
                <span className="start-name"><strong>{l.name}</strong><span>{l.units === 8 ? "Full beginner course" : "First 3 units"}</span></span>
                <Arrow size={16} />
              </a>
            </li>
          );
        })}
      </ul>
      <p className="hint center">Free. No sign-up, no hearts, no ads.</p>
    </div>
  );
}

Change history

Point OpenApps links to openapps.free
8af89d2cc9 · 17 hours ago
Bind agent address in policy
0018350275 · 19 hours ago
Use OpenApps service URLs and add contribution strip
805365daf4 · 19 hours ago
Bounded source sync
3f2fb3b265 · 2 days ago
Bounded source sync
7dcb580324 · 2 days ago
Bounded source sync
dcd05c0944 · 2 days ago