💄 Merge the creator hub and developer hub to the tabs
This commit is contained in:
@@ -5,9 +5,10 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/heatmap.dart';
|
||||
import '../services/responsive.dart';
|
||||
|
||||
/// A reusable heatmap widget for displaying activity data in GitHub-style layout.
|
||||
/// Shows exactly 365 days of data ending at the current date.
|
||||
/// Shows exactly 365 days (wide screen) or 90 days (non-wide screen) of data ending at the current date.
|
||||
class ActivityHeatmapWidget extends HookConsumerWidget {
|
||||
final SnHeatmap heatmap;
|
||||
|
||||
@@ -17,11 +18,13 @@ class ActivityHeatmapWidget extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final selectedItem = useState<HeatmapItem?>(null);
|
||||
|
||||
// Generate exactly 365 days ending at current date
|
||||
final now = DateTime.now();
|
||||
|
||||
// Start from exactly 365 days ago
|
||||
final startDate = now.subtract(const Duration(days: 365));
|
||||
final isWide = isWideScreen(context);
|
||||
final days = isWide ? 365 : 90;
|
||||
|
||||
// Start from exactly the selected days ago
|
||||
final startDate = now.subtract(Duration(days: days));
|
||||
// End at current date
|
||||
final endDate = now;
|
||||
|
||||
@@ -32,7 +35,7 @@ class ActivityHeatmapWidget extends HookConsumerWidget {
|
||||
// Find sunday of the week containing end date
|
||||
final endSunday = endDate.add(Duration(days: 7 - endDate.weekday));
|
||||
|
||||
// Generate weeks to cover exactly 365 days
|
||||
// Generate weeks to cover the selected date range
|
||||
final weeks = <DateTime>[];
|
||||
var current = startMonday;
|
||||
while (current.isBefore(endSunday) || current.isAtSameMomentAs(endSunday)) {
|
||||
@@ -45,7 +48,7 @@ class ActivityHeatmapWidget extends HookConsumerWidget {
|
||||
for (final week in weeks) {
|
||||
for (var i = 0; i < 7; i++) {
|
||||
final date = week.add(Duration(days: i));
|
||||
// Only include dates within our 365-day range
|
||||
// Only include dates within our selected range
|
||||
if (date.isAfter(startDate.subtract(const Duration(days: 1))) &&
|
||||
date.isBefore(endDate.add(const Duration(days: 1)))) {
|
||||
final item = heatmap.items.firstWhere(
|
||||
|
@@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -68,26 +69,28 @@ class WindowScaffold extends HookConsumerWidget {
|
||||
return null;
|
||||
}, []);
|
||||
|
||||
final pageButtonActions = [
|
||||
IconButton(
|
||||
icon: Icon(Symbols.keyboard_arrow_left),
|
||||
onPressed:
|
||||
ref.watch(routerProvider).canPop()
|
||||
? () => ref.read(routerProvider).pop()
|
||||
: null,
|
||||
iconSize: 16,
|
||||
padding: EdgeInsets.all(8),
|
||||
constraints: BoxConstraints(),
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Symbols.home),
|
||||
onPressed: () => ref.read(routerProvider).go('/'),
|
||||
iconSize: 16,
|
||||
padding: EdgeInsets.all(8),
|
||||
constraints: BoxConstraints(),
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
final router = ref.watch(routerProvider);
|
||||
|
||||
final pageActionsButton = [
|
||||
if (router.canPop())
|
||||
IconButton(
|
||||
icon: Icon(Symbols.close),
|
||||
onPressed: router.canPop() ? () => router.pop() : null,
|
||||
iconSize: 16,
|
||||
padding: EdgeInsets.all(8),
|
||||
constraints: BoxConstraints(),
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
icon: Icon(Symbols.home),
|
||||
onPressed: () => router.go('/'),
|
||||
iconSize: 16,
|
||||
padding: EdgeInsets.all(8),
|
||||
constraints: BoxConstraints(),
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
const Gap(8),
|
||||
];
|
||||
|
||||
if (!kIsWeb &&
|
||||
@@ -111,13 +114,18 @@ class WindowScaffold extends HookConsumerWidget {
|
||||
? Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
if (Platform.isMacOS)
|
||||
const SizedBox(width: 80),
|
||||
...pageButtonActions,
|
||||
],
|
||||
),
|
||||
if (isWideScreen(context))
|
||||
Row(
|
||||
key: Key(
|
||||
'app-page-action-${router.state.pageKey.value}',
|
||||
),
|
||||
children: [
|
||||
const Spacer(),
|
||||
...pageActionsButton,
|
||||
],
|
||||
)
|
||||
else
|
||||
SizedBox(height: 32),
|
||||
Text(
|
||||
'Solar Network',
|
||||
textAlign: TextAlign.center,
|
||||
@@ -374,7 +382,7 @@ class PageBackButton extends StatelessWidget {
|
||||
final isDesktop =
|
||||
!kIsWeb && (Platform.isMacOS || Platform.isLinux || Platform.isWindows);
|
||||
|
||||
if (isDesktop) return const SizedBox.shrink();
|
||||
if (isDesktop && isWideScreen(context)) return const SizedBox.shrink();
|
||||
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
@@ -387,9 +395,11 @@ class PageBackButton extends StatelessWidget {
|
||||
},
|
||||
icon: Icon(
|
||||
color: color,
|
||||
(!kIsWeb && (Platform.isMacOS || Platform.isIOS))
|
||||
? Symbols.arrow_back_ios_new
|
||||
: Symbols.arrow_back,
|
||||
context.canPop()
|
||||
? (!kIsWeb && (Platform.isMacOS || Platform.isIOS))
|
||||
? Symbols.arrow_back_ios_new
|
||||
: Symbols.arrow_back
|
||||
: Symbols.home,
|
||||
shadows: shadows,
|
||||
),
|
||||
);
|
||||
|
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/screens/tabs.dart';
|
||||
import 'package:island/services/responsive.dart';
|
||||
|
||||
class ConditionalBottomNav extends HookConsumerWidget {
|
||||
final Widget child;
|
||||
@@ -17,10 +19,11 @@ class ConditionalBottomNav extends HookConsumerWidget {
|
||||
return null;
|
||||
}, [currentLocation]);
|
||||
|
||||
// Use the same route logic as TabsScreen for consistency
|
||||
const mainTabRoutes = ['/', '/chat', '/realms', '/account'];
|
||||
|
||||
final shouldShowBottomNav = mainTabRoutes.contains(currentLocation);
|
||||
final routes = kTabRoutes.sublist(
|
||||
0,
|
||||
isWideScreen(context) ? null : kWideScreenRouteStart,
|
||||
);
|
||||
final shouldShowBottomNav = routes.contains(currentLocation);
|
||||
|
||||
return shouldShowBottomNav ? child : const SizedBox.shrink();
|
||||
}
|
||||
|
Reference in New Issue
Block a user