build method
Build the internal widget.
The context used during the build is passed as is.
Also, WidgetRef is passed to ref to update the state.
内部のウィジェットをビルドします。
ビルド中に使用されるcontextがそのまま渡されます。
また、refに状態を更新するためのPageRefが渡されます。
Implementation
@override
Widget build(BuildContext context, PageRef ref) {
// Describes the process of loading
// and defining variables required for the page.
final adapter = MasamuneModuleSimpleblogMasamuneAdapter.primary;
final auth = adapter.auth.watch(ref);
final note = NoteModel.document(noteId).watch(ref)..load();
final favorite = auth.isSignedIn.select(
onTrue: () =>
FavoriteModel.document(noteId, userId: auth.userId).watch(ref)
..load(),
onFalse: () => null,
);
// Describes the structure of the page.
return UniversalScaffold(
loadingFutures: [
note.loading,
favorite?.loading,
],
loadingWidget: const UniversalColumn(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LineTile(
shimmer: true,
leading: CircleAvatar(),
title: Empty(),
subtitle: Empty(),
),
Divider(),
ShimmerMultiLine(
lineCount: 3,
padding: EdgeInsets.all(16),
),
],
),
appBar: UniversalAppBar(
leadingWhenDisabledPop: CloseButton(
onPressed: () {
adapter.page.index().push(adapter.router);
},
),
actions: [
if (auth.isSignedIn) ...[
if (note.value?.user?.uid == adapter.auth.userId) ...[
IconButton(
onPressed: () {
adapter.page
.noteEditEdit(editId: noteId)
.push(adapter.router);
},
icon: const Icon(Icons.edit),
),
] else ...[
IconButton(
onPressed: () {
if (favorite?.value != null) {
favorite?.delete();
} else {
favorite?.save(FavoriteModel(note: note));
}
},
icon: favorite?.value != null
? const Icon(Icons.favorite)
: const Icon(Icons.favorite_border),
color: favorite?.value != null
? adapter.theme.color.primary
: adapter.theme.color.disabled,
),
],
],
],
),
body: UniversalListView(
onRefresh: () {
return note.reload();
},
children: [
ListTile(
leading: InkWell(
onTap: () {
adapter.page
.profile(userId: note.value?.user?.uid ?? "")
.push(adapter.router);
},
child: CircleAvatar(
backgroundImage:
note.value?.user?.value?.image?.toImageProvider(),
),
),
title: Text(
note.value?.title ?? "",
),
subtitle: Text(note.value?.time.value.yyyyMMddHHmm() ?? ""),
),
const Divider(),
ConstrainedBox(
constraints: const BoxConstraints(minHeight: 420),
child: Padding(
padding: 16.p,
child: SelectableAutoLinkText(
note.value?.text ?? "",
style: adapter.theme.text.bodyLarge,
linkStyle: const TextStyle(color: Colors.blue),
onTap: (link) {
openURL(link);
},
),
),
),
...note.value?.images.map(
(e) {
return Padding(
padding: 16.p,
child: InkWell(
onTap: () {
adapter.page.image(imageUrl: e.value.toString()).push(
adapter.router,
TransitionQuery.fadeModal,
);
},
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image(
image: e.toImageProvider(),
fit: BoxFit.fitWidth,
),
),
),
);
},
) ??
[],
],
),
);
}