diff --git a/.fvm/fvm_config.json b/.fvm/fvm_config.json
index a54bfce7..c15c2874 100644
--- a/.fvm/fvm_config.json
+++ b/.fvm/fvm_config.json
@@ -1,4 +1,4 @@
{
"flutterSdkVersion": "3.14.0-0.2.pre@beta",
"flavors": {}
-}
+}
\ No newline at end of file
diff --git a/assets/Illustration-Conference.svg b/assets/Illustration-Conference.svg
new file mode 100644
index 00000000..d409864c
--- /dev/null
+++ b/assets/Illustration-Conference.svg
@@ -0,0 +1,54 @@
+
diff --git a/lib/app/config.g.dart b/lib/app/config.g.dart
index 3f2bd24a..62eee081 100644
--- a/lib/app/config.g.dart
+++ b/lib/app/config.g.dart
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
+// ignore_for_file: type=lint, duplicate_ignore
part of 'config.dart';
@@ -22,4 +22,5 @@ final configProvider = AutoDisposeProvider.internal(
);
typedef ConfigRef = AutoDisposeProviderRef;
-// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member
diff --git a/lib/app/home_page.dart b/lib/app/home_page.dart
index 27b5f8b4..a17d4c37 100644
--- a/lib/app/home_page.dart
+++ b/lib/app/home_page.dart
@@ -5,6 +5,7 @@ import 'package:confwebsite2023/core/theme.dart';
import 'package:confwebsite2023/features/access/ui/access_widget.dart';
import 'package:confwebsite2023/features/count_down/model/count_down_timer.dart';
import 'package:confwebsite2023/features/count_down/ui/count_down_section.dart';
+import 'package:confwebsite2023/features/event/hands-on/ui/hands_on_event.dart';
import 'package:confwebsite2023/features/footer/ui/footer.dart';
import 'package:confwebsite2023/features/header/data/header_item_button_data.dart';
import 'package:confwebsite2023/features/header/ui/header_widget.dart';
@@ -28,6 +29,7 @@ class MainPage extends HookWidget {
const sectionKeys = (
access: GlobalObjectKey('accessSectionKey'),
event: GlobalObjectKey('eventSectionKey'),
+ ticket: GlobalObjectKey('ticketSectionKey'),
session: GlobalObjectKey('sessionSectionKey'),
sponsor: GlobalObjectKey('sponsorSectionKey'),
staff: GlobalObjectKey('staffSectionKey'),
@@ -42,6 +44,22 @@ class MainPage extends HookWidget {
duration: const Duration(milliseconds: 750),
),
),
+ HeaderItemButtonData(
+ title: 'Event',
+ onPressed: () async => Scrollable.ensureVisible(
+ sectionKeys.event.currentContext!,
+ curve: Curves.easeOutCirc,
+ duration: const Duration(milliseconds: 750),
+ ),
+ ),
+ HeaderItemButtonData(
+ title: 'Ticket',
+ onPressed: () async => Scrollable.ensureVisible(
+ sectionKeys.ticket.currentContext!,
+ curve: Curves.easeOutCirc,
+ duration: const Duration(milliseconds: 750),
+ ),
+ ),
HeaderItemButtonData(
title: 'Staff',
onPressed: () async => Scrollable.ensureVisible(
@@ -74,6 +92,7 @@ class _MainPageBody extends StatelessWidget {
final ({
GlobalObjectKey access,
GlobalObjectKey event,
+ GlobalObjectKey ticket,
GlobalObjectKey session,
GlobalObjectKey sponsor,
GlobalObjectKey staff
@@ -155,17 +174,31 @@ class _MainPageBody extends StatelessWidget {
padding: padding,
child: const NewsSection(),
),
+ const SliverToBoxAdapter(
+ child: Spaces.vertical_200,
+ ),
_Sliver(
padding: padding,
- child: const TicketSection(),
+ child: AccessWidget(
+ key: sectionKeys.access,
+ ),
),
const SliverToBoxAdapter(
child: Spaces.vertical_200,
),
_Sliver(
padding: padding,
- child: AccessWidget(
- key: sectionKeys.access,
+ child: TicketSection(
+ key: sectionKeys.ticket,
+ ),
+ ),
+ const SliverToBoxAdapter(
+ child: Spaces.vertical_200,
+ ),
+ _Sliver(
+ padding: padding,
+ child: HandsOnEvent(
+ key: sectionKeys.event,
),
),
const SliverToBoxAdapter(
diff --git a/lib/core/components/left_filled_icon_button.dart b/lib/core/components/left_filled_icon_button.dart
new file mode 100644
index 00000000..a4797c6f
--- /dev/null
+++ b/lib/core/components/left_filled_icon_button.dart
@@ -0,0 +1,54 @@
+import 'package:confwebsite2023/core/theme.dart';
+import 'package:flutter/material.dart';
+
+class LeftFilledIconButton extends StatelessWidget {
+ const LeftFilledIconButton({
+ required this.onPressed,
+ required this.buttonTitle,
+ required this.icon,
+ super.key,
+ });
+
+ final void Function() onPressed;
+ final String buttonTitle;
+ final IconData icon;
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ final textTheme = theme.textTheme;
+ final colorScheme = theme.colorScheme;
+ return SizedBox(
+ height: 40,
+ child: ElevatedButton(
+ style: ElevatedButton.styleFrom(
+ backgroundColor: colorScheme.primary,
+ padding: const EdgeInsets.symmetric(
+ horizontal: 16,
+ vertical: 8,
+ ),
+ ),
+ onPressed: onPressed,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Spaces.horizontal_8,
+ Text(
+ buttonTitle,
+ style: textTheme.labelLarge?.copyWith(
+ color: colorScheme.onPrimary,
+ ),
+ ),
+ Spaces.horizontal_8,
+ Icon(
+ icon,
+ size: 18,
+ color: colorScheme.onPrimary,
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/core/components/profile_image.dart b/lib/core/components/profile_image.dart
new file mode 100644
index 00000000..e38f2a94
--- /dev/null
+++ b/lib/core/components/profile_image.dart
@@ -0,0 +1,34 @@
+import 'package:flutter/material.dart';
+import 'package:transparent_image/transparent_image.dart';
+
+class ProfileImage extends StatelessWidget {
+ const ProfileImage({
+ required this.imageUrl,
+ required this.size,
+ super.key,
+ });
+ final String imageUrl;
+ final double size;
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ height: size,
+ width: size,
+ child: FittedBox(
+ child: ClipOval(
+ child: FadeInImage(
+ fit: BoxFit.cover,
+ image: NetworkImage(imageUrl),
+ placeholder: MemoryImage(kTransparentImage),
+ imageErrorBuilder: (_, __, ___) => const FittedBox(
+ child: Icon(
+ Icons.error,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/core/components/wanted.dart b/lib/core/components/wanted.dart
index 96b4f81d..2c43f227 100644
--- a/lib/core/components/wanted.dart
+++ b/lib/core/components/wanted.dart
@@ -1,3 +1,4 @@
+import 'package:confwebsite2023/core/components/left_filled_icon_button.dart';
import 'package:confwebsite2023/core/components/responsive_widget.dart';
import 'package:confwebsite2023/core/components/section_header.dart';
import 'package:confwebsite2023/core/theme.dart';
@@ -11,6 +12,7 @@ class WantedWidget extends StatelessWidget {
required this.content,
required this.buttonTitle,
required this.onPressed,
+ this.child,
this.image,
this.subContent,
super.key,
@@ -19,6 +21,7 @@ class WantedWidget extends StatelessWidget {
final String title;
final String content;
final String? subContent;
+ final Widget? child;
final String buttonTitle;
final String? image;
final VoidCallback onPressed;
@@ -26,41 +29,44 @@ class WantedWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ResponsiveWidget(
- largeWidget: WantedDesktop(
+ largeWidget: _WantedDesktop(
title: title,
content: content,
subContent: subContent,
buttonTitle: buttonTitle,
image: image,
onPressed: onPressed,
+ child: child,
),
- smallWidget: WantedMobile(
+ smallWidget: _WantedMobile(
title: title,
content: content,
subContent: subContent,
buttonTitle: buttonTitle,
image: image,
onPressed: onPressed,
+ child: child,
),
);
}
}
-class WantedDesktop extends StatelessWidget {
- const WantedDesktop({
+class _WantedDesktop extends StatelessWidget {
+ const _WantedDesktop({
required this.title,
required this.content,
required this.subContent,
required this.buttonTitle,
required this.image,
required this.onPressed,
- super.key,
+ this.child,
});
final String title;
final String content;
final String? subContent;
final String buttonTitle;
+ final Widget? child;
final String? image;
final VoidCallback onPressed;
@@ -98,45 +104,23 @@ class WantedDesktop extends StatelessWidget {
),
),
Spaces.vertical_24,
- ...switch (subContent) {
- final String body => [
- Text(
- body,
- style: textTheme.bodyMedium!.copyWith(
- color: colorScheme.secondary,
- ),
- ),
- Spaces.vertical_24,
- ],
- null => [],
- },
- SizedBox(
- height: 40,
- child: ElevatedButton(
- style: ElevatedButton.styleFrom(
- backgroundColor: colorScheme.primary,
- ),
- onPressed: onPressed,
- child: Row(
- mainAxisSize: MainAxisSize.min,
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Spaces.horizontal_8,
- Text(
- buttonTitle,
- style: textTheme.labelLarge?.copyWith(
- color: colorScheme.onPrimary,
- ),
- ),
- Spaces.horizontal_8,
- Icon(
- Icons.arrow_forward_ios,
- size: 9,
- color: colorScheme.onPrimary,
- ),
- ],
+ if (subContent != null) ...[
+ Text(
+ subContent!,
+ style: textTheme.bodyMedium!.copyWith(
+ color: colorScheme.secondary,
),
),
+ Spaces.vertical_24,
+ ],
+ if (child != null) ...[
+ child!,
+ Spaces.vertical_24,
+ ],
+ LeftFilledIconButton(
+ onPressed: onPressed,
+ buttonTitle: buttonTitle,
+ icon: Icons.arrow_forward_ios,
),
],
),
@@ -158,15 +142,15 @@ class WantedDesktop extends StatelessWidget {
}
}
-class WantedMobile extends StatelessWidget {
- const WantedMobile({
+class _WantedMobile extends StatelessWidget {
+ const _WantedMobile({
required this.title,
required this.content,
required this.subContent,
required this.buttonTitle,
required this.image,
required this.onPressed,
- super.key,
+ this.child,
});
final String title;
@@ -174,6 +158,7 @@ class WantedMobile extends StatelessWidget {
final String? subContent;
final String buttonTitle;
final String? image;
+ final Widget? child;
final VoidCallback onPressed;
@override
@@ -205,42 +190,23 @@ class WantedMobile extends StatelessWidget {
),
),
Spaces.vertical_24,
- ...switch (subContent) {
- final String body => [
- Text(
- body,
- style: textTheme.bodyMedium!.copyWith(
- color: colorScheme.secondary,
- ),
- ),
- Spaces.vertical_24,
- ],
- null => [],
- },
- SizedBox(
- height: 40,
- child: ElevatedButton(
- style: ElevatedButton.styleFrom(
- backgroundColor: colorScheme.primary,
- ),
- onPressed: onPressed,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text(
- buttonTitle,
- style: textTheme.labelLarge?.copyWith(
- color: colorScheme.onPrimary,
- ),
- ),
- Icon(
- Icons.arrow_forward_ios,
- size: 9,
- color: colorScheme.onPrimary,
- ),
- ],
+ if (subContent != null) ...[
+ Text(
+ subContent!,
+ style: textTheme.bodyMedium!.copyWith(
+ color: colorScheme.secondary,
),
),
+ Spaces.vertical_24,
+ ],
+ if (child != null) ...[
+ child!,
+ Spaces.vertical_24,
+ ],
+ LeftFilledIconButton(
+ onPressed: onPressed,
+ buttonTitle: buttonTitle,
+ icon: Icons.arrow_forward_ios,
),
],
),
diff --git a/lib/core/gen/assets.gen.dart b/lib/core/gen/assets.gen.dart
index a18236bc..d7701065 100644
--- a/lib/core/gen/assets.gen.dart
+++ b/lib/core/gen/assets.gen.dart
@@ -47,6 +47,8 @@ class $AssetsIconsGen {
class Assets {
Assets._();
+ static const String illustrationConference =
+ 'assets/Illustration-Conference.svg';
static const String flutterkaigiLogoShadowed =
'assets/flutterkaigi_logo_shadowed.svg';
static const String flutterkaigiLogoUnion =
@@ -54,7 +56,8 @@ class Assets {
static const $AssetsIconsGen icons = $AssetsIconsGen();
/// List of all assets
- List get values => [flutterkaigiLogoShadowed, flutterkaigiLogoUnion];
+ List get values =>
+ [illustrationConference, flutterkaigiLogoShadowed, flutterkaigiLogoUnion];
}
class AssetGenImage {
diff --git a/lib/features/count_down/model/count_down_timer.g.dart b/lib/features/count_down/model/count_down_timer.g.dart
index 59286c97..0be9a29f 100644
--- a/lib/features/count_down/model/count_down_timer.g.dart
+++ b/lib/features/count_down/model/count_down_timer.g.dart
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
+// ignore_for_file: type=lint, duplicate_ignore
part of 'count_down_timer.dart';
@@ -22,4 +22,5 @@ final nowProvider = AutoDisposeProvider.internal(
);
typedef NowRef = AutoDisposeProviderRef;
-// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member
diff --git a/lib/features/event/hands-on/data/hands_on_staffs_provider.dart b/lib/features/event/hands-on/data/hands_on_staffs_provider.dart
new file mode 100644
index 00000000..1c98f85c
--- /dev/null
+++ b/lib/features/event/hands-on/data/hands_on_staffs_provider.dart
@@ -0,0 +1,14 @@
+import 'package:confwebsite2023/features/staff/data/staff.dart';
+import 'package:confwebsite2023/features/staff/data/staff_provider.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+part 'hands_on_staffs_provider.g.dart';
+
+@riverpod
+Future> handsOnStaff(HandsOnStaffRef ref) async {
+ final staffs = await ref.watch(staffsProvider.future);
+ const handsOnTeamDisplayNames = ['okaryo', 'ちっぴー', '兼高理恵 (robo)', 'jiyuujin'];
+ return staffs
+ .where((staff) => handsOnTeamDisplayNames.contains(staff.displayName))
+ .toList();
+}
diff --git a/lib/features/event/hands-on/data/hands_on_staffs_provider.g.dart b/lib/features/event/hands-on/data/hands_on_staffs_provider.g.dart
new file mode 100644
index 00000000..e08e2f9a
--- /dev/null
+++ b/lib/features/event/hands-on/data/hands_on_staffs_provider.g.dart
@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+// ignore_for_file: type=lint, duplicate_ignore
+
+part of 'hands_on_staffs_provider.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$handsOnStaffHash() => r'6c45dd0845d6b7d0ecfdc1e859c323a8c06fd3f7';
+
+/// See also [handsOnStaff].
+@ProviderFor(handsOnStaff)
+final handsOnStaffProvider = AutoDisposeFutureProvider>.internal(
+ handsOnStaff,
+ name: r'handsOnStaffProvider',
+ debugGetCreateSourceHash:
+ const bool.fromEnvironment('dart.vm.product') ? null : _$handsOnStaffHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+);
+
+typedef HandsOnStaffRef = AutoDisposeFutureProviderRef>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member
diff --git a/lib/features/event/hands-on/ui/hands_on_event.dart b/lib/features/event/hands-on/ui/hands_on_event.dart
new file mode 100644
index 00000000..44b9d49d
--- /dev/null
+++ b/lib/features/event/hands-on/ui/hands_on_event.dart
@@ -0,0 +1,59 @@
+import 'package:confwebsite2023/core/components/profile_image.dart';
+import 'package:confwebsite2023/core/components/wanted.dart';
+import 'package:confwebsite2023/core/gen/assets.gen.dart';
+import 'package:confwebsite2023/features/event/hands-on/data/hands_on_staffs_provider.dart';
+import 'package:confwebsite2023/features/staff/data/staff.dart';
+import 'package:flutter/material.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:url_launcher/url_launcher_string.dart';
+
+class HandsOnEvent extends StatelessWidget {
+ const HandsOnEvent({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ const text =
+ // ignore: lines_longer_than_80_chars
+ '今年のハンズオンでは、三目並べの制作を通してriverpodを学べることを目指します。また、そのチャレンジ企画として Firebase を利用したリアルタイム対戦機能も計画しています。現在、スタッフ一丸となってその準備に励んでおりますので、開催当日まで暫しお待ちいただければと思います。\n'
+ 'なお、開催日は昨年と違い本編とは別日の10/26に開催予定ですので、こちらも合わせてご留意ください。';
+ return WantedWidget(
+ title: 'Join the hands-on event!',
+ buttonTitle: 'イベント詳細',
+ content: text,
+ onPressed: () async => launchUrlString(
+ 'https://flutterkaigi.connpass.com/event/293847/',
+ mode: LaunchMode.externalApplication,
+ ),
+ image: Assets.illustrationConference,
+ child: const _HandsOnStaffsIcon(),
+ );
+ }
+}
+
+class _HandsOnStaffsIcon extends ConsumerWidget {
+ const _HandsOnStaffsIcon();
+
+ @override
+ Widget build(BuildContext context, WidgetRef ref) {
+ final staffs = ref.watch(handsOnStaffProvider);
+
+ return switch ((staffs.valueOrNull, staffs.error)) {
+ (final List data, _) => Wrap(
+ alignment: WrapAlignment.center,
+ runAlignment: WrapAlignment.center,
+ crossAxisAlignment: WrapCrossAlignment.center,
+ spacing: 24,
+ children: data
+ .map(
+ (e) => ProfileImage(
+ imageUrl: e.image.src,
+ size: 120,
+ ),
+ )
+ .toList(),
+ ),
+ (_, final Object error) => Text('例外が発生しました: $error'),
+ (_, _) => const CircularProgressIndicator(),
+ };
+ }
+}
diff --git a/lib/features/news/data/news.freezed.dart b/lib/features/news/data/news.freezed.dart
index ab98573e..9d2b7b0d 100644
--- a/lib/features/news/data/news.freezed.dart
+++ b/lib/features/news/data/news.freezed.dart
@@ -41,7 +41,7 @@ abstract class $NewsCopyWith<$Res> {
String? url,
DateTime startedAt,
@JsonKey(fromJson: _dateTimeFromJson, toJson: _dateTimeToJson)
- DateTime? endedAt});
+ DateTime? endedAt});
}
/// @nodoc
@@ -94,7 +94,7 @@ abstract class _$$_NewsCopyWith<$Res> implements $NewsCopyWith<$Res> {
String? url,
DateTime startedAt,
@JsonKey(fromJson: _dateTimeFromJson, toJson: _dateTimeToJson)
- DateTime? endedAt});
+ DateTime? endedAt});
}
/// @nodoc
@@ -140,7 +140,7 @@ class _$_News implements _News {
required this.url,
required this.startedAt,
@JsonKey(fromJson: _dateTimeFromJson, toJson: _dateTimeToJson)
- required this.endedAt});
+ required this.endedAt});
factory _$_News.fromJson(Map json) => _$$_NewsFromJson(json);
@@ -195,7 +195,7 @@ abstract class _News implements News {
required final String? url,
required final DateTime startedAt,
@JsonKey(fromJson: _dateTimeFromJson, toJson: _dateTimeToJson)
- required final DateTime? endedAt}) = _$_News;
+ required final DateTime? endedAt}) = _$_News;
factory _News.fromJson(Map json) = _$_News.fromJson;
diff --git a/lib/features/news/data/news.g.dart b/lib/features/news/data/news.g.dart
index f4423a13..0532a4e6 100644
--- a/lib/features/news/data/news.g.dart
+++ b/lib/features/news/data/news.g.dart
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
+// ignore_for_file: type=lint, duplicate_ignore
part of 'news.dart';
diff --git a/lib/features/news/data/news_data_source.g.dart b/lib/features/news/data/news_data_source.g.dart
index 3d2a12c7..11587dc2 100644
--- a/lib/features/news/data/news_data_source.g.dart
+++ b/lib/features/news/data/news_data_source.g.dart
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
+// ignore_for_file: type=lint, duplicate_ignore
part of 'news_data_source.dart';
@@ -23,4 +23,5 @@ final newsDataSourceProvider = Provider.internal(
);
typedef NewsDataSourceRef = ProviderRef;
-// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member
diff --git a/lib/features/news/data/news_provider.g.dart b/lib/features/news/data/news_provider.g.dart
index f890fa7c..acf8e484 100644
--- a/lib/features/news/data/news_provider.g.dart
+++ b/lib/features/news/data/news_provider.g.dart
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
+// ignore_for_file: type=lint, duplicate_ignore
part of 'news_provider.dart';
@@ -38,4 +38,5 @@ final currentNewsProvider = AutoDisposeFutureProvider>.internal(
);
typedef CurrentNewsRef = AutoDisposeFutureProviderRef>;
-// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member
diff --git a/lib/features/staff/data/staff.g.dart b/lib/features/staff/data/staff.g.dart
index 4f1bc9d5..90407d89 100644
--- a/lib/features/staff/data/staff.g.dart
+++ b/lib/features/staff/data/staff.g.dart
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
+// ignore_for_file: type=lint, duplicate_ignore
part of 'staff.dart';
diff --git a/lib/features/staff/data/staff_data_source.g.dart b/lib/features/staff/data/staff_data_source.g.dart
index 3adf75fd..a2678cbe 100644
--- a/lib/features/staff/data/staff_data_source.g.dart
+++ b/lib/features/staff/data/staff_data_source.g.dart
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
+// ignore_for_file: type=lint, duplicate_ignore
part of 'staff_data_source.dart';
@@ -23,4 +23,5 @@ final staffDataSourceProvider = Provider.internal(
);
typedef StaffDataSourceRef = ProviderRef;
-// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member
diff --git a/lib/features/staff/data/staff_provider.g.dart b/lib/features/staff/data/staff_provider.g.dart
index b5983ef6..255157fe 100644
--- a/lib/features/staff/data/staff_provider.g.dart
+++ b/lib/features/staff/data/staff_provider.g.dart
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
+// ignore_for_file: type=lint, duplicate_ignore
part of 'staff_provider.dart';
@@ -36,4 +36,5 @@ final sortedStaffsProvider = AutoDisposeFutureProvider>.internal(
);
typedef SortedStaffsRef = AutoDisposeFutureProviderRef>;
-// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member
diff --git a/lib/features/staff/ui/staff_item.dart b/lib/features/staff/ui/staff_item.dart
index d508d2cc..4ede8d70 100644
--- a/lib/features/staff/ui/staff_item.dart
+++ b/lib/features/staff/ui/staff_item.dart
@@ -1,9 +1,9 @@
+import 'package:confwebsite2023/core/components/profile_image.dart';
import 'package:confwebsite2023/core/foundation/iterable_ex.dart';
import 'package:confwebsite2023/core/theme.dart';
import 'package:confwebsite2023/features/staff/data/staff.dart';
import 'package:confwebsite2023/features/staff/ui/sns_icon.dart';
import 'package:flutter/material.dart';
-import 'package:transparent_image/transparent_image.dart';
import 'package:url_launcher/link.dart';
/// ! StaffItemのレイアウト変更時は、`features/staff/ui/staff_table.dart`の
@@ -19,23 +19,9 @@ class StaffItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
- final icon = SizedBox(
- height: 120,
- width: 120,
- child: FittedBox(
- child: ClipOval(
- child: FadeInImage(
- fit: BoxFit.cover,
- image: NetworkImage(staff.image.src),
- placeholder: MemoryImage(kTransparentImage),
- imageErrorBuilder: (_, __, ___) => const FittedBox(
- child: Icon(
- Icons.error,
- ),
- ),
- ),
- ),
- ),
+ final icon = ProfileImage(
+ imageUrl: staff.image.src,
+ size: 120,
);
// IconButtonでは Material Designに基づいて 押しやすいサイズになっているが
// ここでは ボタンの押しやすさより 1行に収めることを優先する
diff --git a/pubspec.lock b/pubspec.lock
index a1414eb8..c64fd2cf 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -85,10 +85,10 @@ packages:
dependency: transitive
description:
name: build_resolvers
- sha256: a7417cc44d9edb3f2c8760000270c99dba8c72ff66d0146772b8326565780745
+ sha256: d912852cce27c9e80a93603db721c267716894462e7033165178b91138587972
url: "https://pub.dev"
source: hosted
- version: "2.3.1"
+ version: "2.3.2"
build_runner:
dependency: "direct dev"
description:
@@ -298,18 +298,18 @@ packages:
dependency: transitive
description:
name: flutter_gen_core
- sha256: e8637dd6a59860f89e5e71be0a27101ec32dad1a0ed7fd879fd23b6e91d5004d
+ sha256: "8b4ff1d45d125e576e26ea99d15e0419bb3c45b53696e022880866b78bb6b830"
url: "https://pub.dev"
source: hosted
- version: "5.3.1"
+ version: "5.3.2"
flutter_gen_runner:
dependency: "direct dev"
description:
name: flutter_gen_runner
- sha256: "7de1bf4fc0439be0fef3178b6423d5c7f1f9f3a38a7c6fafe75d7f70ff4856d7"
+ sha256: fd197f8c657e79313d53d3934de602ebe604ba722a84c88ae3a43cd90428c67a
url: "https://pub.dev"
source: hosted
- version: "5.3.1"
+ version: "5.3.2"
flutter_hooks:
dependency: "direct main"
description:
@@ -327,10 +327,10 @@ packages:
dependency: transitive
description:
name: flutter_riverpod
- sha256: b04d4e9435a563673746ccb328d22018c6c9496bb547e11dd56c1b0cc9829fe5
+ sha256: "1bd39b04f1bcd217a969589777ca6bd642d116e3e5de65c3e6a8e8bdd8b178ec"
url: "https://pub.dev"
source: hosted
- version: "2.3.10"
+ version: "2.4.0"
flutter_svg:
dependency: "direct main"
description:
@@ -401,10 +401,10 @@ packages:
dependency: "direct main"
description:
name: hooks_riverpod
- sha256: "04a8a526db4c04139f6e5d318ef5079832daa1327a485ad391faf1b6bb203960"
+ sha256: ad7b877c3687e38764633d221a1f65491bc7a540e724101e9a404a84db2a4276
url: "https://pub.dev"
source: hosted
- version: "2.3.10"
+ version: "2.4.0"
hotreloader:
dependency: transitive
description:
@@ -641,10 +641,10 @@ packages:
dependency: transitive
description:
name: riverpod
- sha256: "6c0a2c30c04206ac05494bcccd8148b76866e1a9248a5a8c84ca7b16fbcb3f6a"
+ sha256: a600120d6f213a9922860eea1abc32597436edd5b2c4e73b91410f8c2af67d22
url: "https://pub.dev"
source: hosted
- version: "2.3.10"
+ version: "2.4.0"
riverpod_analyzer_utils:
dependency: transitive
description:
@@ -657,10 +657,10 @@ packages:
dependency: "direct main"
description:
name: riverpod_annotation
- sha256: fefc51f8888839a597abe3c813c764404c85c0100a0676d242f358cc92bf5e23
+ sha256: "6294fe7e7d1875f32bdf04c8fce7620e718070273703097847df8f3bf16995ea"
url: "https://pub.dev"
source: hosted
- version: "2.1.4"
+ version: "2.1.5"
riverpod_generator:
dependency: "direct dev"
description:
@@ -958,10 +958,10 @@ packages:
dependency: transitive
description:
name: win32
- sha256: "9e82a402b7f3d518fb9c02d0e9ae45952df31b9bf34d77baf19da2de03fc2aaa"
+ sha256: c97defd418eef4ec88c0d1652cdce84b9f7b63dd7198e266d06ac1710d527067
url: "https://pub.dev"
source: hosted
- version: "5.0.7"
+ version: "5.0.8"
xdg_directories:
dependency: transitive
description: