Joindable chat, detailed realms, discovery mixed into explore

🐛 bunch of bugs fixes
This commit is contained in:
2025-06-28 00:24:43 +08:00
parent 536375729f
commit b8dec9f798
18 changed files with 393 additions and 147 deletions

View File

@ -4,6 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/services/notify.dart';
import 'package:island/services/sharing_intent.dart';
import 'package:island/widgets/tour/tour.dart';
class AppWrapper extends HookConsumerWidget {
final Widget child;
@ -24,6 +25,6 @@ class AppWrapper extends HookConsumerWidget {
};
}, const []);
return child;
return TourTriggerWidget(child: child);
}
}

View File

@ -0,0 +1,100 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/post.dart';
import 'package:island/widgets/content/cloud_files.dart';
class PublisherCard extends ConsumerWidget {
final SnPublisher publisher;
final double? maxWidth;
const PublisherCard({super.key, required this.publisher, this.maxWidth});
@override
Widget build(BuildContext context, WidgetRef ref) {
Widget imageWidget;
if (publisher.picture != null) {
imageWidget = CloudImageWidget(
file: publisher.background,
fit: BoxFit.cover,
);
} else {
imageWidget = ColoredBox(
color: Theme.of(context).colorScheme.secondaryContainer,
);
}
Widget card = Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () {
context.push('/publishers/${publisher.id}');
},
child: AspectRatio(
aspectRatio: 16 / 7,
child: Stack(
fit: StackFit.expand,
children: [
imageWidget,
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Colors.black.withOpacity(0.7),
Colors.transparent,
],
),
),
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: ProfilePictureWidget(
file: publisher.picture,
radius: 12,
),
),
const Gap(2),
Text(
publisher.nick,
style: Theme.of(context).textTheme.titleSmall?.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
),
],
),
),
),
);
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity),
child: card,
);
}
}

View File

@ -1,41 +1,33 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/realm.dart';
import 'package:island/pods/network.dart';
import 'package:island/widgets/content/cloud_files.dart';
import 'package:material_symbols_icons/symbols.dart';
class RealmCard extends ConsumerWidget {
final SnRealm realm;
final double? maxWidth;
const RealmCard({super.key, required this.realm});
const RealmCard({super.key, required this.realm, this.maxWidth});
@override
Widget build(BuildContext context, WidgetRef ref) {
final client = ref.watch(apiClientProvider);
Widget imageWidget;
if (realm.picture != null) {
final imageUrl = '${client.options.baseUrl}/files/${realm.picture!.id}';
imageWidget = Image.network(
imageUrl,
fit: BoxFit.cover,
width: double.infinity,
height: double.infinity,
);
imageWidget =
imageWidget = CloudImageWidget(
file: realm.background,
fit: BoxFit.cover,
);
} else {
imageWidget = Container(
imageWidget = ColoredBox(
color: Theme.of(context).colorScheme.secondaryContainer,
child: Center(
child: Icon(
Symbols.photo_camera,
color: Theme.of(context).colorScheme.onSecondaryContainer,
),
),
);
}
return Card(
Widget card = Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () {
@ -44,6 +36,7 @@ class RealmCard extends ConsumerWidget {
child: AspectRatio(
aspectRatio: 16 / 7,
child: Stack(
fit: StackFit.expand,
children: [
imageWidget,
Positioned(
@ -62,14 +55,37 @@ class RealmCard extends ConsumerWidget {
),
),
padding: const EdgeInsets.all(8),
child: Text(
realm.name,
style: Theme.of(context).textTheme.titleSmall?.copyWith(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: ProfilePictureWidget(
file: realm.picture,
fallbackIcon: Symbols.group,
radius: 12,
),
),
const Gap(2),
Text(
realm.name,
style: Theme.of(context).textTheme.titleSmall?.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
),
@ -78,5 +94,10 @@ class RealmCard extends ConsumerWidget {
),
),
);
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity),
child: card,
);
}
}