Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8f23dd0
feat: enhance sharing messages for plans and passages in the app
dhakar66 Jul 1, 2026
a5f603e
feat: update share message to promote app usage.
dhakar66 Jul 1, 2026
4f4e2c2
feat: implement deep link sharing for mala and timer features and Dai…
dhakar66 Jul 1, 2026
093439f
feat: update Mala screen background color based on theme brightness
tentamdin Jul 1, 2026
3b4d7d0
feat: add deep link support for group sharing, allowing users to invi…
dhakar66 Jul 1, 2026
8050ede
Merge branch 'feature/mala-screen-layout' of https://github.com/OpenP…
tentamdin Jul 1, 2026
1194a07
Merge branch 'develop' of https://github.com/OpenPecha/Flutter-Pecha …
tentamdin Jul 2, 2026
89a8a7c
fix
tentamdin Jul 2, 2026
8e891d4
fix: add user avatar to group accumulator bar
tentamdin Jul 2, 2026
3429c36
fix in tibetan
TenzDelek Jul 2, 2026
ef947d0
feat: improve deep link handling and navigation in the app, preventin…
dhakar66 Jul 2, 2026
d6636ce
remove border and some fix at group card
TenzDelek Jul 2, 2026
efa59fd
changes
TenzDelek Jul 2, 2026
432efad
add enrollment
TenzDelek Jul 2, 2026
c246db6
change
TenzDelek Jul 2, 2026
3bba585
date change
TenzDelek Jul 2, 2026
96f74ab
feat: add functionality to track and add mala rounds completed outsid…
tentamdin Jul 2, 2026
bdda6d0
change
TenzDelek Jul 2, 2026
ddb9442
changes
TenzDelek Jul 2, 2026
c76477f
refactor: enhance MissedDaysBadge widget for improved tap handling an…
dhakar66 Jul 2, 2026
e8ec729
home header fix
TenzDelek Jul 2, 2026
89b8276
refactor: remove border color logic from PracticeTimerCard and Preset…
dhakar66 Jul 2, 2026
583eebc
language
TenzDelek Jul 2, 2026
96d0ef5
refactor: remove border properties from various UI components for a c…
dhakar66 Jul 2, 2026
3133394
feat: implement soft-delete functionality for group accumulators and …
tentamdin Jul 2, 2026
aeaa890
feat: enhance group accumulation tracking with session and lifetime c…
tentamdin Jul 2, 2026
62b0d25
feat: improve group accumulation tracking by incorporating unsynced l…
tentamdin Jul 2, 2026
2f4a852
swipeable tab
TenzDelek Jul 2, 2026
4d15450
Merge pull request #479 from OpenPecha/task/AddDeepLinkToAllShare
tentamdin Jul 2, 2026
3e37813
fix: update group accumulation bar color based on theme brightness
tentamdin Jul 2, 2026
60314ea
localization: add new keys for session and bookmark features across m…
dhakar66 Jul 2, 2026
6f0b0ac
Merge pull request #482 from OpenPecha/feature/mala-screen-layout
tentamdin Jul 2, 2026
232321d
Merge branch 'develop' into bug-fixers
tentamdin Jul 2, 2026
6e833a1
Merge pull request #484 from OpenPecha/bug-fixers
tentamdin Jul 2, 2026
1719f2a
refactor: update bookmarks screen UI for improved design and function…
dhakar66 Jul 2, 2026
f2ac541
refactor: centralize drag handle color logic in ReaderPanelConstants …
dhakar66 Jul 2, 2026
767c424
Merge branch 'develop' into fix/InconsistentUI
dhakar66 Jul 2, 2026
c976899
feat: add stable network image utility functions and refactor image h…
tentamdin Jul 2, 2026
0e0bacb
fix: update localisation
tentamdin Jul 2, 2026
839299d
Merge pull request #486 from OpenPecha/feature/mala-screen-layout
tentamdin Jul 2, 2026
c283e3d
localization: add sharing messages for various features in multiple l…
dhakar66 Jul 2, 2026
be64f9a
Merge pull request #485 from OpenPecha/fix/InconsistentUI
tentamdin Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions android/app/src/main/assets/airbridge.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"sdkEnabled": true,
"logLevel": "info",
"autoStartTrackingEnabled": true,
"sessionTimeoutInSecond": 300,
"hashUserInformationEnabled": true,
"trackAirbridgeDeeplinkOnlyEnabled": true
"sdkEnabled": true,
"logLevel": "info",
"autoStartTrackingEnabled": true,
"sessionTimeoutInSecond": 300,
"hashUserInformationEnabled": true,
"trackAirbridgeDeeplinkOnlyEnabled": true
}
4 changes: 4 additions & 0 deletions lib/core/config/router/app_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ final appRouterProvider = Provider<GoRouter>((ref) {
return GoRouter(
navigatorKey: rootNavigatorKey,
initialLocation: AppRoutes.home,
// App links are consumed explicitly by AppLinksDeepLinkService. If
// go_router also uses the platform launch URL during cold start, the same
// deep link can be inserted twice and leave a stale page under Back.
overridePlatformDefaultLocation: true,
debugLogDiagnostics: true,
observers: [ref.read(analyticsServiceProvider).routeObserver],

Expand Down
4 changes: 4 additions & 0 deletions lib/core/constants/app_assets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ class AppAssets {

// ========== COMMON UI ICONS ==========
static const IconData caretRight = PhosphorIconsRegular.caretRight;
static const IconData caretRight2 = PhosphorIconsBold.caretRight;
static const IconData caretDown = PhosphorIconsRegular.caretDown;
static const IconData caretUp = PhosphorIconsRegular.caretUp;
static const IconData caretLeft = PhosphorIconsRegular.caretLeft;
static const IconData caretLeft2 = PhosphorIconsBold.caretLeft;
static const IconData arrowSquareOut = PhosphorIconsRegular.arrowSquareOut;
static const IconData arrowLeft = PhosphorIconsRegular.arrowLeft;
static const IconData lock = PhosphorIconsRegular.lock;
Expand All @@ -81,7 +83,9 @@ class AppAssets {

// ========== ACTION ICONS ==========
static const IconData plus = PhosphorIconsRegular.plus;
static const IconData plusCircle = PhosphorIconsRegular.plusCircle;
static const IconData minus = PhosphorIconsRegular.minus;
static const IconData minusCircle = PhosphorIconsRegular.minusCircle;
static const IconData play = PhosphorIconsFill.play;
static const IconData pause = PhosphorIconsFill.pause;
static const IconData list = PhosphorIconsRegular.list;
Expand Down
44 changes: 41 additions & 3 deletions lib/core/deep_linking/app_links_deep_link_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ class AppLinksDeepLinkService {
StreamSubscription<Uri>? _subscription;
GoRouter? _router;
Uri? _pendingUri;
Uri? _lastDispatchedUri;
DateTime? _lastDispatchedAt;
bool _initialized = false;
void Function(int tabIndex)? _tabSetter;

static const Duration _duplicateDispatchWindow = Duration(seconds: 5);

Future<void> initialize() async {
if (_initialized) return;
Expand Down Expand Up @@ -50,6 +55,10 @@ class AppLinksDeepLinkService {
_router = router;
}

void setTabSetter(void Function(int tabIndex) setter) {
_tabSetter = setter;
}

bool drainPendingLink() {
if (_router == null) return false;

Expand All @@ -73,6 +82,16 @@ class AppLinksDeepLinkService {
return;
}

if (_pendingUri == uri) {
_logger.debug('Ignoring duplicate pending app link: $uri');
return;
}

if (_wasRecentlyDispatched(uri)) {
_logger.debug('Ignoring recently dispatched app link: $uri');
return;
}

if (_router == null) {
_pendingUri = uri;
_logger.info('Router not ready, stored app link: $uri');
Expand All @@ -82,15 +101,34 @@ class AppLinksDeepLinkService {
_dispatch(uri);
}

void _dispatch(Uri uri, {String? baseLocation}) {
bool _dispatch(Uri uri, {String? baseLocation}) {
final router = _router;
if (router == null) return;
if (router == null) return false;

if (_wasRecentlyDispatched(uri)) {
_logger.debug('Skipping duplicate app link dispatch: $uri');
return false;
}

DeepLinkRouter.route(
final routed = DeepLinkRouter.route(
uri,
router,
source: 'app_links',
baseLocation: baseLocation,
tabSetter: _tabSetter,
);
if (routed) {
_lastDispatchedUri = uri;
_lastDispatchedAt = DateTime.now();
}
return routed;
}

bool _wasRecentlyDispatched(Uri uri) {
final lastUri = _lastDispatchedUri;
final lastAt = _lastDispatchedAt;
if (lastUri != uri || lastAt == null) return false;

return DateTime.now().difference(lastAt) < _duplicateDispatchWindow;
}
}
74 changes: 63 additions & 11 deletions lib/core/deep_linking/deep_link_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class DeepLinkRouter {
GoRouter router, {
required String source,
String? baseLocation,
void Function(int tabIndex)? tabSetter,
}) {
try {
final destination = _resolveRoute(uri);
Expand All @@ -33,6 +34,14 @@ class DeepLinkRouter {
} else {
router.go(destination.location, extra: destination.extra);
}

final tabIndex = destination.tabIndex;
if (tabIndex != null && tabSetter != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
tabSetter(tabIndex);
});
}

return true;
} catch (e, stackTrace) {
_logger.error(
Expand Down Expand Up @@ -67,9 +76,7 @@ class DeepLinkRouter {
}

if (uri.scheme.toLowerCase() == 'webuddhist') {
return _DeepLinkDestination(
_routeForWebuddhistHost(uri.host.toLowerCase()),
);
return _resolveWebuddhistSchemeLink(uri.host.toLowerCase());
}

if (isAirbridgeLink(uri)) {
Expand Down Expand Up @@ -127,39 +134,84 @@ class DeepLinkRouter {
}
}

if (segments.length >= 2 &&
segments[0] == 'open' &&
segments[1] == 'more') {
return const _DeepLinkDestination(AppRoutes.home, tabIndex: _meTabIndex);
}

if (segments.length >= 3 &&
segments[0] == 'open' &&
segments[1] == 'group') {
final groupId = segments[2];
return _DeepLinkDestination(
'/home/group/$groupId',
opensOnTop: true,
);
}

if (segments.length >= 3 &&
segments[0] == 'open' &&
segments[1] == 'mala') {
final presetId = segments[2];
return _DeepLinkDestination(
AppRoutes.mala,
extra: {'presetId': presetId},
opensOnTop: true,
);
}

if (segments.length >= 3 &&
segments[0] == 'open' &&
segments[1] == 'timer') {
return const _DeepLinkDestination(
'/home/timers',
opensOnTop: true,
);
}

return const _DeepLinkDestination(AppRoutes.home);
}

static String _routeForWebuddhistHost(String host) {
static _DeepLinkDestination _resolveWebuddhistSchemeLink(String host) {
switch (host) {
case 'open':
case 'home':
return AppRoutes.home;
return const _DeepLinkDestination(AppRoutes.home);
case 'practice':
return AppRoutes.practice;
return const _DeepLinkDestination(AppRoutes.practice);
case 'texts':
return AppRoutes.texts;
return const _DeepLinkDestination(AppRoutes.texts);
case 'more':
return AppRoutes.more;
return const _DeepLinkDestination(AppRoutes.home, tabIndex: _meTabIndex);
case 'profile':
return AppRoutes.profile;
return const _DeepLinkDestination(AppRoutes.profile);
case 'notifications':
return AppRoutes.notifications;
return const _DeepLinkDestination(AppRoutes.notifications);
default:
_logger.warning('Unknown webuddhist deep link host: $host');
return AppRoutes.home;
return const _DeepLinkDestination(AppRoutes.home);
}
}
}

/// Bottom nav tab index for the Me screen (matches MainTab.me.index == 3).
const int _meTabIndex = 3;

class _DeepLinkDestination {
final String location;
final Object? extra;
final bool opensOnTop;

/// When non-null, the deep-link handler should switch the bottom nav bar to
/// this tab index after navigating. Used for tab-based screens that share
/// the `/home` route (e.g. the Me tab).
final int? tabIndex;

const _DeepLinkDestination(
this.location, {
this.extra,
this.opensOnTop = false,
this.tabIndex,
});
}
28 changes: 28 additions & 0 deletions lib/core/deep_linking/deep_link_url_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,32 @@ class DeepLinkUrlBuilder {
queryParameters: queryParameters,
);
}

static Uri moreLink() {
return Uri(scheme: 'https', host: _host, pathSegments: ['open', 'more']);
}

static Uri groupLink({required String groupId}) {
return Uri(
scheme: 'https',
host: _host,
pathSegments: ['open', 'group', groupId],
);
}

static Uri malaLink({required String presetId}) {
return Uri(
scheme: 'https',
host: _host,
pathSegments: ['open', 'mala', presetId],
);
}

static Uri timerLink({required String timerId}) {
return Uri(
scheme: 'https',
host: _host,
pathSegments: ['open', 'timer', timerId],
);
}
}
26 changes: 26 additions & 0 deletions lib/core/l10n/app_bo.arb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@
"home_shortcut_plans": "ཉམས་ལེན།",
"home_chants": "ཞལ་འདོན།",
"home_mala": "ཕྲེང་བ།",
"session_mala": "ཕྲེང་བ་རྣམས།",
"bookmark_mala": "ཕྲེང་བ་རྣམས།",
"bookmark_timers": "སྒོམ་ཐུན་རྣམས།",
"bookmark_texts": "གསུང་རབ།",
"mala_add_to_practice": "ངའི་ཉམས་ལེན་ནང་སྣོན།",
"mala_add_mala_round": "Add mala round",
"mala_add_rounds_title": "Add mala rounds:",
"mala_add_rounds_message": "Add the number of mala rounds you did outside this app.",
"mala_add_to_bookmark": "དཔེ་རྟགས།",
"mala_sound": "སྒྲ།",
"mala_vibration": "འདར་འགུལ།",
Expand Down Expand Up @@ -710,10 +717,29 @@
"group_links_title": "འབྲེལ་ཐག",
"group_and_more_links": "དང་འབྲེལ་ཐག་གཞན་ {count}",
"group_practice_with_us": "ང་ཚོ་དང་མཉམ་དུ་སྒོམ་གྱི།",
"group_join_to_contribute": "བསགས་གྲངས་སྐྱེལ་ཆེད་ཞུགས།",
"group_accumulator_join_error": "བསགས་གྲངས་ལ་ཞུགས་མ་ཐུབ། ཡང་བསྐྱར་ཚོད་ལྟ་གནང་རོགས།",
"group_accumulator_participants": "མཉམ་ཞུགས་པ་ {count}",
"group_accumulator_leaderboard": "རིམ་པའི་ཐོ།",
"group_accumulator_my_contributions": "ངའི་སྐྱེལ་མ།",
"group_accumulator_recited": "བཟླས་བརྗོད།",
"group_accumulator_total": "ཁྱོན་བསྡོམས།",
"group_accumulator_contributions_empty": "ཁྱེད་ཀྱི་སྐྱེལ་མ་ལ་རྗེས་འདེད་བྱེད་ཆེད་བསགས་གྲངས་འདིར་ཞུགས་རོགས།",
"group_accumulator_recite_now": "ད་ལྟ་བཟླས་བརྗོད་གནང་།",

"share_this_quote": "གསུང་ཚིག་འདི་སྤེལ།",
"shared_from": "སྤེལ་ཁུངས།",
"verse_share_error": "གསུང་ཚིག་སྤེལ་མ་ཐུབ། བསྐྱར་དུ་ཚོད་ལྟ་བྱོས།",
"share_app_message": "ངས་ཉིན་རེའི་ནང་ཆོས་ཉམས་ལེན་གྱི་སྤྱོད་ལམ་སྦྱོང་བར་འཕྲིན་ཆས་འདི་བཀོལ་སྤྱོད་བྱེད་ཀྱི་ཡོད། ཁྱོད་ཀྱིས་ཀྱང་ལས་དེ་དགའ་བར་ངས་བསམ་གྱི་ཡོད།",
"share_streak_message": "ངས་ཉིན་རེའི་ཉམས་ལེན་གྱི་དུས་ཚོད་གསབ་སྐྱོང་བྱེད་མཁན་ཞིག་ཡིན་པ་ཁྱོད་དང་མཉམ་དུ་བགྲོ་གླེང་བྱེད་འདོད། གྲོགས་པོ་མཉམ་ཞུགས་ཀྱིས་ཉམས་ལེན་སྤེལ་ཐབས་སྟབས་བདེ་ཆེར་འགྲོ། WeBuddhist ཐོག་ང་མཉམ་ཞུགས་མཛོད།",
"share_chant_message": "ངས་མགུར་འདི་ཁྱོད་དང་མཉམ་བགྲོ་བར་འདོད། ཁྱོད་ཀྱིས་དེ་ཉམས་ལེན་བྱེད་ཐུབ་ཅིང་ WeBuddhist ཐོག་མགུར་གཞུང་ཆེན་པོའི་མཛོད་དུ་རྒྱུ་ཐུབ།",
"share_quote_message": "WeBuddhist ཐོག་གི་གསུང་ཚིག་འདི་ངར་དགར་སོང་བས་ཁྱོད་དང་མཉམ་བགྲོ་བར་འདོད། WeBuddhist ཉེར་སྤྱོད་ཐོག་ལྟ་ཀློག་ཕྱི་བཀྲམ་གྱི་ཚིག་རྒྱུག་མང་པོ་དཔྱད།",
"share_mala_message": "ངས་ WeBuddhist ཐོག་གི་གློག་རྡུལ་ཕྲེང་བ་འདི་བཀོལ་སྤྱོད་བྱེད་ཀྱི་ཡོད་ཅིང་ཁྱོད་དང་མཉམ་བགྲོ་བར་འདོད། གང་དུ་ཡིན་ཡང་ཉམས་ལེན་བྱེད་ལ་ཐབས་སྟབས་བདེ་བ་ཞིག་ཡིན།",
"share_passage_message": "ངས་ཚིགས་མ་འདི་དགར་སོང་བས་ཁྱོད་དང་མཉམ་བགྲོ་བར་འདོད། ཁྱོད་ཀྱིས་ WeBuddhist ཐོག་གི་ཚིག་རྒྱུག་མཐར་ཐུག་གི་ལྟ་ཀློག་བྱེད་ཐུབ།",
"share_timer_message": "ངས་ WeBuddhist ཐོག་གི་བསམ་གཏན་དུས་ཚོད་རྩིས་འདི་ཁྱོད་དང་མཉམ་བགྲོ་བར་འདོད། བསམ་གཏན་གྱི་ཉམས་ལེན་ཡར་སྤེལ་བར་ཐབས་སྟབས་བདེ།",
"share_plan_message": "ངས་ཆོས་ཉམས་ལེན་གྱི་འཆར་གཞི་འདི་རྗེས་སུ་འབྲང་ཞིང་ཁྱོད་དང་མཉམ་བགྲོ་བར་འདོད། ཁྱོད་ཀྱིས་ WeBuddhist ཐོག་གིས་རིན་མེད་ང་མཉམ་ཞུགས་བྱེད་ཐུབ།",
"share_plan_subject": "WeBuddhist ཐོག་ང་མཉམ་ཞུགས་མཛོད།",
"share_group_invite_message": "ངའི་སྡེ་ཚན་དུ་ཁྱོད་ཞུགས་ན་སྙིང་གི་དགའ་བ། WeBuddhist ཐོག་མཉམ་དུ་ཉམས་ལེན་བྱོས།",
"connect_subtitle": "ཁྱེད་ཀྱི་ཚོགས་པ་བཙལ་ཏེ་མཉམ་དུ་ཉམས་ལེན་བྱོས།",
"discover_groups": "ཚོགས་པ་འཚོལ།",
"my_groups": "ངའི་ཚོགས་པ།",
Expand Down
18 changes: 18 additions & 0 deletions lib/core/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@
"home_shortcut_plans": "Plans",
"home_chants": "Chants",
"home_mala": "Mala",
"session_mala": "Malas",
"bookmark_mala": "Malas",
"bookmark_timers": "Timers",
"bookmark_texts": "Texts",
"mala_add_to_practice": "Add to my practices",
"mala_add_mala_round": "Add mala round",
"mala_add_rounds_title": "Add mala rounds:",
"mala_add_rounds_message": "Add the number of mala rounds you did outside this app.",
"mala_add_to_bookmark": "Bookmark",
"mala_sound": "Sound",
"mala_vibration": "Vibration",
Expand Down Expand Up @@ -804,6 +811,7 @@
"group_accumulator_recited": "Recited",
"group_accumulator_total": "Total",
"group_accumulator_contributions_empty": "Join this accumulation to track your contributions.",
"group_accumulator_recite_now": "Recite now",
"@group_and_more_links": {
"placeholders": {
"count": {
Expand All @@ -815,6 +823,16 @@
"share_this_quote": "Share this quote",
"shared_from": "Shared from",
"verse_share_error": "Unable to share quote. Please try again",
"share_app_message": "I've been using this app to build a daily Buddhist practice, and thought you'd love it.",
"share_streak_message": "I've been building a daily practice habit and wanted to share it with you. It's easier to keep it up with a friend. Join me on WeBuddhist.",
"share_chant_message": "I wanted to share this chant with you. You can practice it and find a whole library of other chants and texts on WeBuddhist.",
"share_quote_message": "I liked this quote from WeBuddhist and wanted to share it with you. Read more such insightful quotes on the WeBuddhist App",
"share_mala_message": "I've been using this digital mala on WeBuddhist and wanted to share it with you. It's an easy way to practice wherever you go.",
"share_passage_message": "I liked this passage and wanted to share it with you. You can read the whole quote in context on WeBuddhist.",
"share_timer_message": "I wanted to share this meditation timer from WeBuddhist with you. It makes it easy to build a meditation practice.",
"share_plan_message": "I'm following this Buddhist practice plan and wanted to share it with you. You can join me for free on WeBuddhist.",
"share_plan_subject": "Join me on WeBuddhist",
"share_group_invite_message": "I'd love for you to join our group. Let's practice together on WeBuddhist.",
"weekday_monday": "MON",
"weekday_tuesday": "TUE",
"weekday_wednesday": "WED",
Expand Down
Loading
Loading