Skip to content

Repository files navigation

Don't Drink

Small daily choices. Big long-term changes.

A mobile app that helps you reduce or eliminate alcohol consumption through daily tracking, streaks, achievements, education, and motivation.


Features

Daily Tracker

Log exactly one status per day by tapping any date. Five levels:

StatusColorMeaning
No DrinksGreen0 alcoholic drinks
1–2 DrinksYellowLight drinking
3–5 DrinksOrangeModerate drinking
6+ DrinksRedHeavy drinking
BlackoutBlackExtreme drinking / memory loss

You can edit any past day. Future days are disabled.

Streak Counter

The dashboard shows your current alcohol-free streak and your all-time longest streak. If today hasn't been logged yet, the streak is measured through yesterday so the counter doesn't reset just from not opening the app.

Color-Coded Calendar

Browse any month's color-coded grid. Navigate backward month by month. Tap any day to log or edit it.

Achievement System

Nine streak milestones unlock automatically — based on your longest ever streak, so a relapse doesn't erase a badge. Legendary milestones fire a confetti celebration.

DayAchievement
1Better Liver Begins
3Better Hydration
7Better Sleep
14More Energy
30One Month Strong ⭐
60Mental Clarity
90New Lifestyle ⭐
180Half-Year Champion ⭐
365One Year Alcohol-Free ⭐

Statistics

Bar chart of alcohol-free days over the last 6 months, a pie chart of drink-level distribution, and a headline overview (longest streak, free-day rate, best month).

Recovery Timeline

A milestone timeline showing what the body gains hour-by-hour and month-by-month when alcohol-free — with your current streak highlighted as "reached."

Facts & Education

A daily rotating fact card plus browsable lists of alcohol harms and benefits of not drinking.

Motivation

Swipeable full-bleed motivation cards. Tap Inspire me to jump to a random one.

Daily Reminder (optional)

An on-device scheduled notification at a time you choose (default 8:00 PM). Can be toggled off at any time. Requires notification permission.

Theme

Light, dark, or system-default — switchable in Settings.


Architecture

lib/
├── core/
│ ├── models/ # DrinkLevel, DayEntry, Achievement
│ ├── theme/ # AppTheme (Material 3), AppColors
│ └── utils/ # DateOnly helpers
├── data/
│ ├── database/ # AppDatabase (SQLite via sqflite)
│ ├── repositories/ # EntryRepository, SettingsRepository
│ └── static/ # Achievements, facts, recovery, motivation
├── services/ # StatsService, AchievementService, NotificationService
├── viewmodels/ # TrackerViewModel, SettingsViewModel (ChangeNotifier / Provider)
└── ui/
├── dashboard/
├── calendar/
├── achievements/
├── statistics/
├── recovery/
├── facts/
├── motivation/
├── settings/
├── more/
├── shell/ # HomeShell (NavigationBar)
└── widgets/ # AppCard, DayEntrySheet, AchievementUnlockDialog, ...

Pattern: MVVM. ViewModels extend ChangeNotifier and are provided via provider. Screens read from ViewModels and call ViewModel methods; they do not touch the database directly. All data is local (SQLite + SharedPreferences).


Building

Prerequisites

ToolVersion
Flutter (via fvm)3.41.2 stable
Dart3.11.0
Android SDKat ~/Android/Sdk
Android NDK28.2 (installed in ~/Android/Sdk/ndk/)
Java17+

Flutter is managed by fvm. The project's .fvm/ config pins the version automatically.

Note — SDK path:android/local.properties points at ~/Android/Sdk. If Flutter rewrites it back to /opt/android-sdk during pub get, change sdk.dir back to /home/ben/Android/Sdk. The /opt SDK has no NDK and no accepted licenses.

Run the app

# With fvm on PATH (or use the full path):
flutter pub get
flutter run

Build a debug APK

flutter build apk --debug
# Output: build/app/outputs/flutter-apk/app-debug.apk

Build a release APK

flutter build apk --release

Run tests

flutter test

Covers streak calculation, longest-streak detection, monthly aggregation, and stats computation (7 unit tests in test/stats_service_test.dart).

Static analysis

flutter analyze
# Expected: No issues found

Android Manifest Notes

The app declares POST_NOTIFICATIONS and RECEIVE_BOOT_COMPLETED permissions for the optional daily reminder. No network permission is declared — the app is fully offline.


Dependencies

PackagePurpose
providerMVVM state management
sqfliteLocal SQLite database
shared_preferencesTheme + notification preferences
fl_chartStatistics charts
confettiAchievement milestone celebrations
flutter_local_notificationsOptional daily reminder
timezoneReliable local-time scheduling
intlDate formatting
google_fontsInter typeface
pathDatabase path construction

About

reduce or stop consumption

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - 13/dontdrink: reduce or stop consumption · GitHub
Skip to content

Repository files navigation

Don't Drink

Small daily choices. Big long-term changes.

A mobile app that helps you reduce or eliminate alcohol consumption through daily tracking, streaks, achievements, education, and motivation.


Features

Daily Tracker

Log exactly one status per day by tapping any date. Five levels:

StatusColorMeaning
No DrinksGreen0 alcoholic drinks
1–2 DrinksYellowLight drinking
3–5 DrinksOrangeModerate drinking
6+ DrinksRedHeavy drinking
BlackoutBlackExtreme drinking / memory loss

You can edit any past day. Future days are disabled.

Streak Counter

The dashboard shows your current alcohol-free streak and your all-time longest streak. If today hasn't been logged yet, the streak is measured through yesterday so the counter doesn't reset just from not opening the app.

Color-Coded Calendar

Browse any month's color-coded grid. Navigate backward month by month. Tap any day to log or edit it.

Achievement System

Nine streak milestones unlock automatically — based on your longest ever streak, so a relapse doesn't erase a badge. Legendary milestones fire a confetti celebration.

DayAchievement
1Better Liver Begins
3Better Hydration
7Better Sleep
14More Energy
30One Month Strong ⭐
60Mental Clarity
90New Lifestyle ⭐
180Half-Year Champion ⭐
365One Year Alcohol-Free ⭐

Statistics

Bar chart of alcohol-free days over the last 6 months, a pie chart of drink-level distribution, and a headline overview (longest streak, free-day rate, best month).

Recovery Timeline

A milestone timeline showing what the body gains hour-by-hour and month-by-month when alcohol-free — with your current streak highlighted as "reached."

Facts & Education

A daily rotating fact card plus browsable lists of alcohol harms and benefits of not drinking.

Motivation

Swipeable full-bleed motivation cards. Tap Inspire me to jump to a random one.

Daily Reminder (optional)

An on-device scheduled notification at a time you choose (default 8:00 PM). Can be toggled off at any time. Requires notification permission.

Theme

Light, dark, or system-default — switchable in Settings.


Architecture

lib/
├── core/
│ ├── models/ # DrinkLevel, DayEntry, Achievement
│ ├── theme/ # AppTheme (Material 3), AppColors
│ └── utils/ # DateOnly helpers
├── data/
│ ├── database/ # AppDatabase (SQLite via sqflite)
│ ├── repositories/ # EntryRepository, SettingsRepository
│ └── static/ # Achievements, facts, recovery, motivation
├── services/ # StatsService, AchievementService, NotificationService
├── viewmodels/ # TrackerViewModel, SettingsViewModel (ChangeNotifier / Provider)
└── ui/
├── dashboard/
├── calendar/
├── achievements/
├── statistics/
├── recovery/
├── facts/
├── motivation/
├── settings/
├── more/
├── shell/ # HomeShell (NavigationBar)
└── widgets/ # AppCard, DayEntrySheet, AchievementUnlockDialog, ...

Pattern: MVVM. ViewModels extend ChangeNotifier and are provided via provider. Screens read from ViewModels and call ViewModel methods; they do not touch the database directly. All data is local (SQLite + SharedPreferences).


Building

Prerequisites

ToolVersion
Flutter (via fvm)3.41.2 stable
Dart3.11.0
Android SDKat ~/Android/Sdk
Android NDK28.2 (installed in ~/Android/Sdk/ndk/)
Java17+

Flutter is managed by fvm. The project's .fvm/ config pins the version automatically.

Note — SDK path:android/local.properties points at ~/Android/Sdk. If Flutter rewrites it back to /opt/android-sdk during pub get, change sdk.dir back to /home/ben/Android/Sdk. The /opt SDK has no NDK and no accepted licenses.

Run the app

# With fvm on PATH (or use the full path):
flutter pub get
flutter run

Build a debug APK

flutter build apk --debug
# Output: build/app/outputs/flutter-apk/app-debug.apk

Build a release APK

flutter build apk --release

Run tests

flutter test

Covers streak calculation, longest-streak detection, monthly aggregation, and stats computation (7 unit tests in test/stats_service_test.dart).

Static analysis

flutter analyze
# Expected: No issues found

Android Manifest Notes

The app declares POST_NOTIFICATIONS and RECEIVE_BOOT_COMPLETED permissions for the optional daily reminder. No network permission is declared — the app is fully offline.


Dependencies

PackagePurpose
providerMVVM state management
sqfliteLocal SQLite database
shared_preferencesTheme + notification preferences
fl_chartStatistics charts
confettiAchievement milestone celebrations
flutter_local_notificationsOptional daily reminder
timezoneReliable local-time scheduling
intlDate formatting
google_fontsInter typeface
pathDatabase path construction

About

reduce or stop consumption

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - 13/dontdrink: reduce or stop consumption · GitHub
Skip to content

Repository files navigation

Don't Drink

Small daily choices. Big long-term changes.

A mobile app that helps you reduce or eliminate alcohol consumption through daily tracking, streaks, achievements, education, and motivation.


Features

Daily Tracker

Log exactly one status per day by tapping any date. Five levels:

StatusColorMeaning
No DrinksGreen0 alcoholic drinks
1–2 DrinksYellowLight drinking
3–5 DrinksOrangeModerate drinking
6+ DrinksRedHeavy drinking
BlackoutBlackExtreme drinking / memory loss

You can edit any past day. Future days are disabled.

Streak Counter

The dashboard shows your current alcohol-free streak and your all-time longest streak. If today hasn't been logged yet, the streak is measured through yesterday so the counter doesn't reset just from not opening the app.

Color-Coded Calendar

Browse any month's color-coded grid. Navigate backward month by month. Tap any day to log or edit it.

Achievement System

Nine streak milestones unlock automatically — based on your longest ever streak, so a relapse doesn't erase a badge. Legendary milestones fire a confetti celebration.

DayAchievement
1Better Liver Begins
3Better Hydration
7Better Sleep
14More Energy
30One Month Strong ⭐
60Mental Clarity
90New Lifestyle ⭐
180Half-Year Champion ⭐
365One Year Alcohol-Free ⭐

Statistics

Bar chart of alcohol-free days over the last 6 months, a pie chart of drink-level distribution, and a headline overview (longest streak, free-day rate, best month).

Recovery Timeline

A milestone timeline showing what the body gains hour-by-hour and month-by-month when alcohol-free — with your current streak highlighted as "reached."

Facts & Education

A daily rotating fact card plus browsable lists of alcohol harms and benefits of not drinking.

Motivation

Swipeable full-bleed motivation cards. Tap Inspire me to jump to a random one.

Daily Reminder (optional)

An on-device scheduled notification at a time you choose (default 8:00 PM). Can be toggled off at any time. Requires notification permission.

Theme

Light, dark, or system-default — switchable in Settings.


Architecture

lib/
├── core/
│ ├── models/ # DrinkLevel, DayEntry, Achievement
│ ├── theme/ # AppTheme (Material 3), AppColors
│ └── utils/ # DateOnly helpers
├── data/
│ ├── database/ # AppDatabase (SQLite via sqflite)
│ ├── repositories/ # EntryRepository, SettingsRepository
│ └── static/ # Achievements, facts, recovery, motivation
├── services/ # StatsService, AchievementService, NotificationService
├── viewmodels/ # TrackerViewModel, SettingsViewModel (ChangeNotifier / Provider)
└── ui/
├── dashboard/
├── calendar/
├── achievements/
├── statistics/
├── recovery/
├── facts/
├── motivation/
├── settings/
├── more/
├── shell/ # HomeShell (NavigationBar)
└── widgets/ # AppCard, DayEntrySheet, AchievementUnlockDialog, ...

Pattern: MVVM. ViewModels extend ChangeNotifier and are provided via provider. Screens read from ViewModels and call ViewModel methods; they do not touch the database directly. All data is local (SQLite + SharedPreferences).


Building

Prerequisites

ToolVersion
Flutter (via fvm)3.41.2 stable
Dart3.11.0
Android SDKat ~/Android/Sdk
Android NDK28.2 (installed in ~/Android/Sdk/ndk/)
Java17+

Flutter is managed by fvm. The project's .fvm/ config pins the version automatically.

Note — SDK path:android/local.properties points at ~/Android/Sdk. If Flutter rewrites it back to /opt/android-sdk during pub get, change sdk.dir back to /home/ben/Android/Sdk. The /opt SDK has no NDK and no accepted licenses.

Run the app

# With fvm on PATH (or use the full path):
flutter pub get
flutter run

Build a debug APK

flutter build apk --debug
# Output: build/app/outputs/flutter-apk/app-debug.apk

Build a release APK

flutter build apk --release

Run tests

flutter test

Covers streak calculation, longest-streak detection, monthly aggregation, and stats computation (7 unit tests in test/stats_service_test.dart).

Static analysis

flutter analyze
# Expected: No issues found

Android Manifest Notes

The app declares POST_NOTIFICATIONS and RECEIVE_BOOT_COMPLETED permissions for the optional daily reminder. No network permission is declared — the app is fully offline.


Dependencies

PackagePurpose
providerMVVM state management
sqfliteLocal SQLite database
shared_preferencesTheme + notification preferences
fl_chartStatistics charts
confettiAchievement milestone celebrations
flutter_local_notificationsOptional daily reminder
timezoneReliable local-time scheduling
intlDate formatting
google_fontsInter typeface
pathDatabase path construction

About

reduce or stop consumption

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - 13/dontdrink: reduce or stop consumption · GitHub
Skip to content

Repository files navigation

Don't Drink

Small daily choices. Big long-term changes.

A mobile app that helps you reduce or eliminate alcohol consumption through daily tracking, streaks, achievements, education, and motivation.


Features

Daily Tracker

Log exactly one status per day by tapping any date. Five levels:

StatusColorMeaning
No DrinksGreen0 alcoholic drinks
1–2 DrinksYellowLight drinking
3–5 DrinksOrangeModerate drinking
6+ DrinksRedHeavy drinking
BlackoutBlackExtreme drinking / memory loss

You can edit any past day. Future days are disabled.

Streak Counter

The dashboard shows your current alcohol-free streak and your all-time longest streak. If today hasn't been logged yet, the streak is measured through yesterday so the counter doesn't reset just from not opening the app.

Color-Coded Calendar

Browse any month's color-coded grid. Navigate backward month by month. Tap any day to log or edit it.

Achievement System

Nine streak milestones unlock automatically — based on your longest ever streak, so a relapse doesn't erase a badge. Legendary milestones fire a confetti celebration.

DayAchievement
1Better Liver Begins
3Better Hydration
7Better Sleep
14More Energy
30One Month Strong ⭐
60Mental Clarity
90New Lifestyle ⭐
180Half-Year Champion ⭐
365One Year Alcohol-Free ⭐

Statistics

Bar chart of alcohol-free days over the last 6 months, a pie chart of drink-level distribution, and a headline overview (longest streak, free-day rate, best month).

Recovery Timeline

A milestone timeline showing what the body gains hour-by-hour and month-by-month when alcohol-free — with your current streak highlighted as "reached."

Facts & Education

A daily rotating fact card plus browsable lists of alcohol harms and benefits of not drinking.

Motivation

Swipeable full-bleed motivation cards. Tap Inspire me to jump to a random one.

Daily Reminder (optional)

An on-device scheduled notification at a time you choose (default 8:00 PM). Can be toggled off at any time. Requires notification permission.

Theme

Light, dark, or system-default — switchable in Settings.


Architecture

lib/
├── core/
│ ├── models/ # DrinkLevel, DayEntry, Achievement
│ ├── theme/ # AppTheme (Material 3), AppColors
│ └── utils/ # DateOnly helpers
├── data/
│ ├── database/ # AppDatabase (SQLite via sqflite)
│ ├── repositories/ # EntryRepository, SettingsRepository
│ └── static/ # Achievements, facts, recovery, motivation
├── services/ # StatsService, AchievementService, NotificationService
├── viewmodels/ # TrackerViewModel, SettingsViewModel (ChangeNotifier / Provider)
└── ui/
├── dashboard/
├── calendar/
├── achievements/
├── statistics/
├── recovery/
├── facts/
├── motivation/
├── settings/
├── more/
├── shell/ # HomeShell (NavigationBar)
└── widgets/ # AppCard, DayEntrySheet, AchievementUnlockDialog, ...

Pattern: MVVM. ViewModels extend ChangeNotifier and are provided via provider. Screens read from ViewModels and call ViewModel methods; they do not touch the database directly. All data is local (SQLite + SharedPreferences).


Building

Prerequisites

ToolVersion
Flutter (via fvm)3.41.2 stable
Dart3.11.0
Android SDKat ~/Android/Sdk
Android NDK28.2 (installed in ~/Android/Sdk/ndk/)
Java17+

Flutter is managed by fvm. The project's .fvm/ config pins the version automatically.

Note — SDK path:android/local.properties points at ~/Android/Sdk. If Flutter rewrites it back to /opt/android-sdk during pub get, change sdk.dir back to /home/ben/Android/Sdk. The /opt SDK has no NDK and no accepted licenses.

Run the app

# With fvm on PATH (or use the full path):
flutter pub get
flutter run

Build a debug APK

flutter build apk --debug
# Output: build/app/outputs/flutter-apk/app-debug.apk

Build a release APK

flutter build apk --release

Run tests

flutter test

Covers streak calculation, longest-streak detection, monthly aggregation, and stats computation (7 unit tests in test/stats_service_test.dart).

Static analysis

flutter analyze
# Expected: No issues found

Android Manifest Notes

The app declares POST_NOTIFICATIONS and RECEIVE_BOOT_COMPLETED permissions for the optional daily reminder. No network permission is declared — the app is fully offline.


Dependencies

PackagePurpose
providerMVVM state management
sqfliteLocal SQLite database
shared_preferencesTheme + notification preferences
fl_chartStatistics charts
confettiAchievement milestone celebrations
flutter_local_notificationsOptional daily reminder
timezoneReliable local-time scheduling
intlDate formatting
google_fontsInter typeface
pathDatabase path construction

About

reduce or stop consumption

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - 13/dontdrink: reduce or stop consumption · GitHub
Skip to content

Repository files navigation

Don't Drink

Small daily choices. Big long-term changes.

A mobile app that helps you reduce or eliminate alcohol consumption through daily tracking, streaks, achievements, education, and motivation.


Features

Daily Tracker

Log exactly one status per day by tapping any date. Five levels:

StatusColorMeaning
No DrinksGreen0 alcoholic drinks
1–2 DrinksYellowLight drinking
3–5 DrinksOrangeModerate drinking
6+ DrinksRedHeavy drinking
BlackoutBlackExtreme drinking / memory loss

You can edit any past day. Future days are disabled.

Streak Counter

The dashboard shows your current alcohol-free streak and your all-time longest streak. If today hasn't been logged yet, the streak is measured through yesterday so the counter doesn't reset just from not opening the app.

Color-Coded Calendar

Browse any month's color-coded grid. Navigate backward month by month. Tap any day to log or edit it.

Achievement System

Nine streak milestones unlock automatically — based on your longest ever streak, so a relapse doesn't erase a badge. Legendary milestones fire a confetti celebration.

DayAchievement
1Better Liver Begins
3Better Hydration
7Better Sleep
14More Energy
30One Month Strong ⭐
60Mental Clarity
90New Lifestyle ⭐
180Half-Year Champion ⭐
365One Year Alcohol-Free ⭐

Statistics

Bar chart of alcohol-free days over the last 6 months, a pie chart of drink-level distribution, and a headline overview (longest streak, free-day rate, best month).

Recovery Timeline

A milestone timeline showing what the body gains hour-by-hour and month-by-month when alcohol-free — with your current streak highlighted as "reached."

Facts & Education

A daily rotating fact card plus browsable lists of alcohol harms and benefits of not drinking.

Motivation

Swipeable full-bleed motivation cards. Tap Inspire me to jump to a random one.

Daily Reminder (optional)

An on-device scheduled notification at a time you choose (default 8:00 PM). Can be toggled off at any time. Requires notification permission.

Theme

Light, dark, or system-default — switchable in Settings.


Architecture

lib/
├── core/
│ ├── models/ # DrinkLevel, DayEntry, Achievement
│ ├── theme/ # AppTheme (Material 3), AppColors
│ └── utils/ # DateOnly helpers
├── data/
│ ├── database/ # AppDatabase (SQLite via sqflite)
│ ├── repositories/ # EntryRepository, SettingsRepository
│ └── static/ # Achievements, facts, recovery, motivation
├── services/ # StatsService, AchievementService, NotificationService
├── viewmodels/ # TrackerViewModel, SettingsViewModel (ChangeNotifier / Provider)
└── ui/
├── dashboard/
├── calendar/
├── achievements/
├── statistics/
├── recovery/
├── facts/
├── motivation/
├── settings/
├── more/
├── shell/ # HomeShell (NavigationBar)
└── widgets/ # AppCard, DayEntrySheet, AchievementUnlockDialog, ...

Pattern: MVVM. ViewModels extend ChangeNotifier and are provided via provider. Screens read from ViewModels and call ViewModel methods; they do not touch the database directly. All data is local (SQLite + SharedPreferences).


Building

Prerequisites

ToolVersion
Flutter (via fvm)3.41.2 stable
Dart3.11.0
Android SDKat ~/Android/Sdk
Android NDK28.2 (installed in ~/Android/Sdk/ndk/)
Java17+

Flutter is managed by fvm. The project's .fvm/ config pins the version automatically.

Note — SDK path:android/local.properties points at ~/Android/Sdk. If Flutter rewrites it back to /opt/android-sdk during pub get, change sdk.dir back to /home/ben/Android/Sdk. The /opt SDK has no NDK and no accepted licenses.

Run the app

# With fvm on PATH (or use the full path):
flutter pub get
flutter run

Build a debug APK

flutter build apk --debug
# Output: build/app/outputs/flutter-apk/app-debug.apk

Build a release APK

flutter build apk --release

Run tests

flutter test

Covers streak calculation, longest-streak detection, monthly aggregation, and stats computation (7 unit tests in test/stats_service_test.dart).

Static analysis

flutter analyze
# Expected: No issues found

Android Manifest Notes

The app declares POST_NOTIFICATIONS and RECEIVE_BOOT_COMPLETED permissions for the optional daily reminder. No network permission is declared — the app is fully offline.


Dependencies

PackagePurpose
providerMVVM state management
sqfliteLocal SQLite database
shared_preferencesTheme + notification preferences
fl_chartStatistics charts
confettiAchievement milestone celebrations
flutter_local_notificationsOptional daily reminder
timezoneReliable local-time scheduling
intlDate formatting
google_fontsInter typeface
pathDatabase path construction

About

reduce or stop consumption

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - 13/dontdrink: reduce or stop consumption · GitHub
Skip to content

Repository files navigation

Don't Drink

Small daily choices. Big long-term changes.

A mobile app that helps you reduce or eliminate alcohol consumption through daily tracking, streaks, achievements, education, and motivation.


Features

Daily Tracker

Log exactly one status per day by tapping any date. Five levels:

StatusColorMeaning
No DrinksGreen0 alcoholic drinks
1–2 DrinksYellowLight drinking
3–5 DrinksOrangeModerate drinking
6+ DrinksRedHeavy drinking
BlackoutBlackExtreme drinking / memory loss

You can edit any past day. Future days are disabled.

Streak Counter

The dashboard shows your current alcohol-free streak and your all-time longest streak. If today hasn't been logged yet, the streak is measured through yesterday so the counter doesn't reset just from not opening the app.

Color-Coded Calendar

Browse any month's color-coded grid. Navigate backward month by month. Tap any day to log or edit it.

Achievement System

Nine streak milestones unlock automatically — based on your longest ever streak, so a relapse doesn't erase a badge. Legendary milestones fire a confetti celebration.

DayAchievement
1Better Liver Begins
3Better Hydration
7Better Sleep
14More Energy
30One Month Strong ⭐
60Mental Clarity
90New Lifestyle ⭐
180Half-Year Champion ⭐
365One Year Alcohol-Free ⭐

Statistics

Bar chart of alcohol-free days over the last 6 months, a pie chart of drink-level distribution, and a headline overview (longest streak, free-day rate, best month).

Recovery Timeline

A milestone timeline showing what the body gains hour-by-hour and month-by-month when alcohol-free — with your current streak highlighted as "reached."

Facts & Education

A daily rotating fact card plus browsable lists of alcohol harms and benefits of not drinking.

Motivation

Swipeable full-bleed motivation cards. Tap Inspire me to jump to a random one.

Daily Reminder (optional)

An on-device scheduled notification at a time you choose (default 8:00 PM). Can be toggled off at any time. Requires notification permission.

Theme

Light, dark, or system-default — switchable in Settings.


Architecture

lib/
├── core/
│ ├── models/ # DrinkLevel, DayEntry, Achievement
│ ├── theme/ # AppTheme (Material 3), AppColors
│ └── utils/ # DateOnly helpers
├── data/
│ ├── database/ # AppDatabase (SQLite via sqflite)
│ ├── repositories/ # EntryRepository, SettingsRepository
│ └── static/ # Achievements, facts, recovery, motivation
├── services/ # StatsService, AchievementService, NotificationService
├── viewmodels/ # TrackerViewModel, SettingsViewModel (ChangeNotifier / Provider)
└── ui/
├── dashboard/
├── calendar/
├── achievements/
├── statistics/
├── recovery/
├── facts/
├── motivation/
├── settings/
├── more/
├── shell/ # HomeShell (NavigationBar)
└── widgets/ # AppCard, DayEntrySheet, AchievementUnlockDialog, ...

Pattern: MVVM. ViewModels extend ChangeNotifier and are provided via provider. Screens read from ViewModels and call ViewModel methods; they do not touch the database directly. All data is local (SQLite + SharedPreferences).


Building

Prerequisites

ToolVersion
Flutter (via fvm)3.41.2 stable
Dart3.11.0
Android SDKat ~/Android/Sdk
Android NDK28.2 (installed in ~/Android/Sdk/ndk/)
Java17+

Flutter is managed by fvm. The project's .fvm/ config pins the version automatically.

Note — SDK path:android/local.properties points at ~/Android/Sdk. If Flutter rewrites it back to /opt/android-sdk during pub get, change sdk.dir back to /home/ben/Android/Sdk. The /opt SDK has no NDK and no accepted licenses.

Run the app

# With fvm on PATH (or use the full path):
flutter pub get
flutter run

Build a debug APK

flutter build apk --debug
# Output: build/app/outputs/flutter-apk/app-debug.apk

Build a release APK

flutter build apk --release

Run tests

flutter test

Covers streak calculation, longest-streak detection, monthly aggregation, and stats computation (7 unit tests in test/stats_service_test.dart).

Static analysis

flutter analyze
# Expected: No issues found

Android Manifest Notes

The app declares POST_NOTIFICATIONS and RECEIVE_BOOT_COMPLETED permissions for the optional daily reminder. No network permission is declared — the app is fully offline.


Dependencies

PackagePurpose
providerMVVM state management
sqfliteLocal SQLite database
shared_preferencesTheme + notification preferences
fl_chartStatistics charts
confettiAchievement milestone celebrations
flutter_local_notificationsOptional daily reminder
timezoneReliable local-time scheduling
intlDate formatting
google_fontsInter typeface
pathDatabase path construction

About

reduce or stop consumption

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - 13/dontdrink: reduce or stop consumption · GitHub
Skip to content

Repository files navigation

Don't Drink

Small daily choices. Big long-term changes.

A mobile app that helps you reduce or eliminate alcohol consumption through daily tracking, streaks, achievements, education, and motivation.


Features

Daily Tracker

Log exactly one status per day by tapping any date. Five levels:

StatusColorMeaning
No DrinksGreen0 alcoholic drinks
1–2 DrinksYellowLight drinking
3–5 DrinksOrangeModerate drinking
6+ DrinksRedHeavy drinking
BlackoutBlackExtreme drinking / memory loss

You can edit any past day. Future days are disabled.

Streak Counter

The dashboard shows your current alcohol-free streak and your all-time longest streak. If today hasn't been logged yet, the streak is measured through yesterday so the counter doesn't reset just from not opening the app.

Color-Coded Calendar

Browse any month's color-coded grid. Navigate backward month by month. Tap any day to log or edit it.

Achievement System

Nine streak milestones unlock automatically — based on your longest ever streak, so a relapse doesn't erase a badge. Legendary milestones fire a confetti celebration.

DayAchievement
1Better Liver Begins
3Better Hydration
7Better Sleep
14More Energy
30One Month Strong ⭐
60Mental Clarity
90New Lifestyle ⭐
180Half-Year Champion ⭐
365One Year Alcohol-Free ⭐

Statistics

Bar chart of alcohol-free days over the last 6 months, a pie chart of drink-level distribution, and a headline overview (longest streak, free-day rate, best month).

Recovery Timeline

A milestone timeline showing what the body gains hour-by-hour and month-by-month when alcohol-free — with your current streak highlighted as "reached."

Facts & Education

A daily rotating fact card plus browsable lists of alcohol harms and benefits of not drinking.

Motivation

Swipeable full-bleed motivation cards. Tap Inspire me to jump to a random one.

Daily Reminder (optional)

An on-device scheduled notification at a time you choose (default 8:00 PM). Can be toggled off at any time. Requires notification permission.

Theme

Light, dark, or system-default — switchable in Settings.


Architecture

lib/
├── core/
│ ├── models/ # DrinkLevel, DayEntry, Achievement
│ ├── theme/ # AppTheme (Material 3), AppColors
│ └── utils/ # DateOnly helpers
├── data/
│ ├── database/ # AppDatabase (SQLite via sqflite)
│ ├── repositories/ # EntryRepository, SettingsRepository
│ └── static/ # Achievements, facts, recovery, motivation
├── services/ # StatsService, AchievementService, NotificationService
├── viewmodels/ # TrackerViewModel, SettingsViewModel (ChangeNotifier / Provider)
└── ui/
├── dashboard/
├── calendar/
├── achievements/
├── statistics/
├── recovery/
├── facts/
├── motivation/
├── settings/
├── more/
├── shell/ # HomeShell (NavigationBar)
└── widgets/ # AppCard, DayEntrySheet, AchievementUnlockDialog, ...

Pattern: MVVM. ViewModels extend ChangeNotifier and are provided via provider. Screens read from ViewModels and call ViewModel methods; they do not touch the database directly. All data is local (SQLite + SharedPreferences).


Building

Prerequisites

ToolVersion
Flutter (via fvm)3.41.2 stable
Dart3.11.0
Android SDKat ~/Android/Sdk
Android NDK28.2 (installed in ~/Android/Sdk/ndk/)
Java17+

Flutter is managed by fvm. The project's .fvm/ config pins the version automatically.

Note — SDK path:android/local.properties points at ~/Android/Sdk. If Flutter rewrites it back to /opt/android-sdk during pub get, change sdk.dir back to /home/ben/Android/Sdk. The /opt SDK has no NDK and no accepted licenses.

Run the app

# With fvm on PATH (or use the full path):
flutter pub get
flutter run

Build a debug APK

flutter build apk --debug
# Output: build/app/outputs/flutter-apk/app-debug.apk

Build a release APK

flutter build apk --release

Run tests

flutter test

Covers streak calculation, longest-streak detection, monthly aggregation, and stats computation (7 unit tests in test/stats_service_test.dart).

Static analysis

flutter analyze
# Expected: No issues found

Android Manifest Notes

The app declares POST_NOTIFICATIONS and RECEIVE_BOOT_COMPLETED permissions for the optional daily reminder. No network permission is declared — the app is fully offline.


Dependencies

PackagePurpose
providerMVVM state management
sqfliteLocal SQLite database
shared_preferencesTheme + notification preferences
fl_chartStatistics charts
confettiAchievement milestone celebrations
flutter_local_notificationsOptional daily reminder
timezoneReliable local-time scheduling
intlDate formatting
google_fontsInter typeface
pathDatabase path construction

About

reduce or stop consumption

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - 13/dontdrink: reduce or stop consumption · GitHub
Skip to content

Repository files navigation

Don't Drink

Small daily choices. Big long-term changes.

A mobile app that helps you reduce or eliminate alcohol consumption through daily tracking, streaks, achievements, education, and motivation.


Features

Daily Tracker

Log exactly one status per day by tapping any date. Five levels:

StatusColorMeaning
No DrinksGreen0 alcoholic drinks
1–2 DrinksYellowLight drinking
3–5 DrinksOrangeModerate drinking
6+ DrinksRedHeavy drinking
BlackoutBlackExtreme drinking / memory loss

You can edit any past day. Future days are disabled.

Streak Counter

The dashboard shows your current alcohol-free streak and your all-time longest streak. If today hasn't been logged yet, the streak is measured through yesterday so the counter doesn't reset just from not opening the app.

Color-Coded Calendar

Browse any month's color-coded grid. Navigate backward month by month. Tap any day to log or edit it.

Achievement System

Nine streak milestones unlock automatically — based on your longest ever streak, so a relapse doesn't erase a badge. Legendary milestones fire a confetti celebration.

DayAchievement
1Better Liver Begins
3Better Hydration
7Better Sleep
14More Energy
30One Month Strong ⭐
60Mental Clarity
90New Lifestyle ⭐
180Half-Year Champion ⭐
365One Year Alcohol-Free ⭐

Statistics

Bar chart of alcohol-free days over the last 6 months, a pie chart of drink-level distribution, and a headline overview (longest streak, free-day rate, best month).

Recovery Timeline

A milestone timeline showing what the body gains hour-by-hour and month-by-month when alcohol-free — with your current streak highlighted as "reached."

Facts & Education

A daily rotating fact card plus browsable lists of alcohol harms and benefits of not drinking.

Motivation

Swipeable full-bleed motivation cards. Tap Inspire me to jump to a random one.

Daily Reminder (optional)

An on-device scheduled notification at a time you choose (default 8:00 PM). Can be toggled off at any time. Requires notification permission.

Theme

Light, dark, or system-default — switchable in Settings.


Architecture

lib/
├── core/
│ ├── models/ # DrinkLevel, DayEntry, Achievement
│ ├── theme/ # AppTheme (Material 3), AppColors
│ └── utils/ # DateOnly helpers
├── data/
│ ├── database/ # AppDatabase (SQLite via sqflite)
│ ├── repositories/ # EntryRepository, SettingsRepository
│ └── static/ # Achievements, facts, recovery, motivation
├── services/ # StatsService, AchievementService, NotificationService
├── viewmodels/ # TrackerViewModel, SettingsViewModel (ChangeNotifier / Provider)
└── ui/
├── dashboard/
├── calendar/
├── achievements/
├── statistics/
├── recovery/
├── facts/
├── motivation/
├── settings/
├── more/
├── shell/ # HomeShell (NavigationBar)
└── widgets/ # AppCard, DayEntrySheet, AchievementUnlockDialog, ...

Pattern: MVVM. ViewModels extend ChangeNotifier and are provided via provider. Screens read from ViewModels and call ViewModel methods; they do not touch the database directly. All data is local (SQLite + SharedPreferences).


Building

Prerequisites

ToolVersion
Flutter (via fvm)3.41.2 stable
Dart3.11.0
Android SDKat ~/Android/Sdk
Android NDK28.2 (installed in ~/Android/Sdk/ndk/)
Java17+

Flutter is managed by fvm. The project's .fvm/ config pins the version automatically.

Note — SDK path:android/local.properties points at ~/Android/Sdk. If Flutter rewrites it back to /opt/android-sdk during pub get, change sdk.dir back to /home/ben/Android/Sdk. The /opt SDK has no NDK and no accepted licenses.

Run the app

# With fvm on PATH (or use the full path):
flutter pub get
flutter run

Build a debug APK

flutter build apk --debug
# Output: build/app/outputs/flutter-apk/app-debug.apk

Build a release APK

flutter build apk --release

Run tests

flutter test

Covers streak calculation, longest-streak detection, monthly aggregation, and stats computation (7 unit tests in test/stats_service_test.dart).

Static analysis

flutter analyze
# Expected: No issues found

Android Manifest Notes

The app declares POST_NOTIFICATIONS and RECEIVE_BOOT_COMPLETED permissions for the optional daily reminder. No network permission is declared — the app is fully offline.


Dependencies

PackagePurpose
providerMVVM state management
sqfliteLocal SQLite database
shared_preferencesTheme + notification preferences
fl_chartStatistics charts
confettiAchievement milestone celebrations
flutter_local_notificationsOptional daily reminder
timezoneReliable local-time scheduling
intlDate formatting
google_fontsInter typeface
pathDatabase path construction

About

reduce or stop consumption

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages