TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
브라우저에서 근무시간 카운트다운을 설정해 시작·종료 시각과 진행률을 표시, 계정 없이 기기에 저장, 선택적 수입 표시
A work-hour countdown in your browser. Set start and end times — overnight included — and watch remaining time and progress. Stays on this device, no account. Optional earnings. Shift planning is on i
생산성Swift · KotlinGitHub @ififi2017온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Countdown to the end of your workday — in the browser, or as a menu bar / tray app for macOS, iOS / iPadOS and Windows. Free, no sign-up, offline, 19 languages.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Off Work Countdown is now DoneAt.
DoneAt is a privacy-friendly countdown for the end of your workday,
available on the Web, as a lightweight Tauri desktop app, and as a native
iPhone and iPad app on the App Store. Set your schedule once, then keep the
remaining time, progress and estimated earnings at a glance.README 전문 보기 ↗Off Work Countdown is now DoneAt.
DoneAt is a privacy-friendly countdown for the end of your workday, available on the Web, as a lightweight Tauri desktop app, as a native iPhone and iPad app on the App Store, and as a native Android app on Google Play. Set your schedule once, then keep the remaining time, progress and estimated earnings at a glance.
The iOS app is native SwiftUI and shares the same schedule rules as Web and Desktop. iPhone, iPad and Mac share one App Store listing. The Android app is native Kotlin and follows the same schedule rules.
The desktop app adds a menu-bar countdown on macOS, a compact always-on-top mini timer on Windows, native notifications, launch at login, a global shortcut and one-click updates. It remains local-first: schedules, salary settings and countdown state stay on your device.
On launch the app asks GitHub whether a newer version exists. That request
carries no account, salary or usage data, and the installer is downloaded only
after you choose to update. If GitHub cannot be reached directly — common on
some networks — the update panel offers a one-click retry through a public
mirror (gh-proxy.com). The mirror only changes where the bytes come from:
every updater package is verified against the signing key built into the app
before it is installed, so a tampered download is rejected either way. To point
at a different mirror or drop it entirely, change MIRROR_UPDATER_ENDPOINT in
src-tauri/src/lib.rs, UPDATE_MIRROR_HOST in lib/desktop-state.ts and
MIRROR_PREFIX in scripts/mirror-manifest.mjs.
The current builds are open source but are not signed with paid Apple or Microsoft code-signing certificates. The updater packages are cryptographically signed for Tauri's update verification, but macOS Gatekeeper or Windows SmartScreen may still warn on first installation. Download only from this repository's Release page and verify that the tag and filename match your platform.
The two store builds are the exception: Microsoft and Apple sign them during certification, so they install without any warning and update through the store rather than through the in-app updater.
The Mac App Store build skips all of this: Apple signs it, so it installs in one click with no Gatekeeper detour, and it carries a countdown widget. It needs macOS 13 (Ventura) or later. On macOS 14 (Sonoma) or later the widget can sit on the desktop; on macOS 13 it lives in Notification Center. The steps below are for the GitHub DMGs, which stay available either way.
The DMGs require macOS 11.3 (Big Sur) or later, on Apple Silicon or Intel.
aarch64.dmg for Apple Silicon or x64.dmg for an Intel Mac.The Microsoft Store build is the smoothest route — no SmartScreen prompt, and the Store keeps it updated. The steps below are for the direct installers.
x64-setup.exe for most PCs, or arm64-setup.exe for a Windows on
ARM device. The MSI files are also available for managed installation.Your hours and salary are stored only in your browser, desktop app, iPhone or iPad. They are never sent to a server, and nothing is synchronised between devices. Optional Web analytics record only allowlisted aggregate event counts—no salary, schedule, cookies, IP addresses or device identifiers.
git clone https://github.com/ififi2017/Off-Work-Countdown.git
cd Off-Work-Countdown
npm install
echo "NEXT_PUBLIC_BASE_URL=http://localhost:3000" > .env.local
npm run dev
Other useful scripts:
npm run lint # ESLint
npm test # Vitest unit tests
npm run build # Production build (web)
npm run build:desktop # Static export for the desktop app, output in out/
npm run build:extension # Chrome popup, output in build/chrome-extension/
Chrome extension setup and behavior: Chrome extension guide.
Release automation for maintainers:
npm run deploy:web # Validate and push committed main
npm run deploy:web -- --dry-run # Validate without pushing
npm run release:desktop # Release package.json's version
npm run release:desktop -- 3.0.3 # Explicitly verify and release 3.0.3
npm run release:desktop -- --dry-run # Run every release check, no tag
Both publishing commands require a clean main branch and fetch the remote
before acting. Desktop release additionally requires HEAD to equal
origin/main, rejects duplicate tags and asks you to type the exact tag before
it pushes. Pass --yes only in an intentionally non-interactive environment.
Note: next dev and next build share the .next directory. Running a build
while the dev server is up will leave the dev server serving chunks that no
longer exist. Stop the dev server first, or delete .next afterwards.
The site configuration is centralized in config/site.ts:
export const siteConfig = {
brandName: "DoneAt",
webAppUrl: "https://off.rainif.com",
officialSiteUrl: "https://doneat.app",
github: "https://github.com/ififi2017/Off-Work-Countdown",
themeColor: "#F3F4F6",
} as const;
Aggregate event counters for the share funnel. Entirely optional — with no environment variables set, the endpoint accepts requests and does nothing, so local development, CI and self-hosted deployments work without any setup.
No cookies, no identifiers, no IP or user-agent storage: the endpoint only
increments a daily counter per event name, and only for names on a fixed
allowlist (lib/analytics-events.ts).
| Variable | Purpose |
|---|---|
UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN | Upstash Redis REST credentials. KV_REST_API_URL / KV_REST_API_TOKEN are also accepted. |
ANALYTICS_STATS_TOKEN | Enables the read-back route. Unset means /api/e/stats returns 404. |
On Vercel, add an Upstash Redis integration from the Marketplace and the credentials are injected automatically. Read the counters with:
curl -H "Authorization: Bearer $ANALYTICS_STATS_TOKEN" https://your-domain/api/e/stats
The endpoint is public, so counts can be inflated by anyone willing to POST to it. Treat the numbers as a directional signal, not a source of truth.
Language configuration is managed in i18n-config.ts:
export const defaultLocale = 'en'
export const locales = ['en', 'zh-CN', 'zh-TW', ...] as const
// Language code mapping
export const languageMapping = {
'zh': 'zh-CN',
'zh-Hans': 'zh-CN',
// ... more mappings
}
// Language display names
export const languageNames = {
'en': 'English',
'zh-CN': '简体中文',
// ... more names
}
Long-form FAQ, how-it-works, about, download and privacy live on
doneat.app. Old URLs on this site permanently redirect
there. Schedule preset pages (/en/996, /ja/9-to-5, etc.) are available in
all 19 supported languages (lib/content-locales.ts exports presetLocales).
For Search Console, submit https://off.rainif.com/sitemap.xml only — see
docs/seo.md.
This app supports Progressive Web App features, allowing you to install it on your device and use it offline. To install:
On iPhone and iPad the native App Store app is the one with widgets and Live Activities. The PWA path is still there if you prefer it: use the Share button in Safari and choose "Add to Home Screen". On macOS Safari, choose "Add to Dock".
The PWA is still supported, but desktop users who want a persistent menu-bar or mini-timer experience, native reminders, launch at login and automatic updates should use the desktop app.
Contributions are welcome! Please feel free to submit a Pull Request.
plans/iOS/005-product-3.0.md records the current roadmap along with the reasoning behind
the decisions — including the things that were considered and deliberately not
built.
We're looking to expand our app's language support. If you'd like to contribute translations:
locales array in i18n-config.ts.public/locales/[lang]/:
translation.json - for UI stringsseo.json - for SEO metadataThose two files are all a new language needs. Schedule presets (presets.json)
are available in all 19 supported languages — add preset translations when
adding a new locale.
DoneAt's source code is available under MPL-2.0, unless otherwise noted. Commercial forks are allowed; distribution carries the applicable source-availability and notice obligations. See LICENSING.md and source for releases.
Previously granted MIT rights remain in effect; the original notice is in LICENSES/MIT-legacy.txt. DoneAt branding and designated artwork are excluded from new MPL grants: see ASSETS.md and TRADEMARKS.md. Independent releases must not impersonate DoneAt. Third-party components keep their own licenses.
New contributions follow CONTRIBUTING.md.
The bundled Geist fonts in app/fonts/ are licensed separately under the
SIL Open Font License 1.1.
Special thanks to: