✨ Realm avatar, banner
This commit is contained in:
parent
c9fbe47337
commit
565a8e41cc
@ -228,6 +228,8 @@
|
|||||||
"realmDescription": "Description",
|
"realmDescription": "Description",
|
||||||
"realmPublic": "Public Realm",
|
"realmPublic": "Public Realm",
|
||||||
"realmCommunity": "Community Realm",
|
"realmCommunity": "Community Realm",
|
||||||
|
"realmAvatar": "Realm avatar",
|
||||||
|
"realmBanner": "Realm banner",
|
||||||
"realmDetail": "Realm detail",
|
"realmDetail": "Realm detail",
|
||||||
"realmMember": "Realm member",
|
"realmMember": "Realm member",
|
||||||
"realmMembers": "Realm members",
|
"realmMembers": "Realm members",
|
||||||
|
@ -229,6 +229,8 @@
|
|||||||
"realmDescription": "领域简介",
|
"realmDescription": "领域简介",
|
||||||
"realmPublic": "公开领域",
|
"realmPublic": "公开领域",
|
||||||
"realmCommunity": "社区领域",
|
"realmCommunity": "社区领域",
|
||||||
|
"realmAvatar": "领域头像",
|
||||||
|
"realmBanner": "领域横幅",
|
||||||
"realmDetail": "领域详情",
|
"realmDetail": "领域详情",
|
||||||
"realmMember": "领域成员",
|
"realmMember": "领域成员",
|
||||||
"realmMembers": "领域成员",
|
"realmMembers": "领域成员",
|
||||||
|
@ -5,7 +5,7 @@ import 'package:solian/models/realm.dart';
|
|||||||
import 'package:solian/screens/about.dart';
|
import 'package:solian/screens/about.dart';
|
||||||
import 'package:solian/screens/account.dart';
|
import 'package:solian/screens/account.dart';
|
||||||
import 'package:solian/screens/account/friend.dart';
|
import 'package:solian/screens/account/friend.dart';
|
||||||
import 'package:solian/screens/account/personalize.dart';
|
import 'package:solian/screens/account/profile_edit.dart';
|
||||||
import 'package:solian/screens/account/profile_page.dart';
|
import 'package:solian/screens/account/profile_page.dart';
|
||||||
import 'package:solian/screens/auth/signin.dart';
|
import 'package:solian/screens/auth/signin.dart';
|
||||||
import 'package:solian/screens/auth/signup.dart';
|
import 'package:solian/screens/auth/signup.dart';
|
||||||
|
@ -114,7 +114,7 @@ class _ChannelDetailScreenState extends State<ChannelDetailScreen> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.settings),
|
leading: const Icon(Icons.settings),
|
||||||
trailing: const Icon(Icons.chevron_right),
|
trailing: const Icon(Icons.chevron_right),
|
||||||
title: Text('channelSettings'.tr.capitalize!),
|
title: Text('channelSettings'.tr),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
AppRouter.instance
|
AppRouter.instance
|
||||||
.pushNamed(
|
.pushNamed(
|
||||||
@ -173,7 +173,7 @@ class _ChannelDetailScreenState extends State<ChannelDetailScreen> {
|
|||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.notifications_active),
|
leading: const Icon(Icons.notifications_active),
|
||||||
title: Text('channelNotifyLevel'.tr.capitalize!),
|
title: Text('channelNotifyLevel'.tr),
|
||||||
trailing: DropdownButtonHideUnderline(
|
trailing: DropdownButtonHideUnderline(
|
||||||
child: DropdownButton2<int>(
|
child: DropdownButton2<int>(
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
@ -208,7 +208,7 @@ class _ChannelDetailScreenState extends State<ChannelDetailScreen> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.supervisor_account),
|
leading: const Icon(Icons.supervisor_account),
|
||||||
trailing: const Icon(Icons.chevron_right),
|
trailing: const Icon(Icons.chevron_right),
|
||||||
title: Text('channelMembers'.tr.capitalize!),
|
title: Text('channelMembers'.tr),
|
||||||
onTap: () => showMemberList(),
|
onTap: () => showMemberList(),
|
||||||
),
|
),
|
||||||
...(_isOwned ? ownerActions : List.empty()),
|
...(_isOwned ? ownerActions : List.empty()),
|
||||||
|
@ -97,6 +97,14 @@ class _ChannelOrganizeScreenState extends State<ChannelOrganizeScreen> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_aliasController.dispose();
|
||||||
|
_nameController.dispose();
|
||||||
|
_descriptionController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final notifyBannerActions = [
|
final notifyBannerActions = [
|
||||||
|
@ -7,10 +7,13 @@ import 'package:solian/providers/auth.dart';
|
|||||||
import 'package:solian/providers/content/realm.dart';
|
import 'package:solian/providers/content/realm.dart';
|
||||||
import 'package:solian/router.dart';
|
import 'package:solian/router.dart';
|
||||||
import 'package:solian/screens/account/notification.dart';
|
import 'package:solian/screens/account/notification.dart';
|
||||||
|
import 'package:solian/services.dart';
|
||||||
import 'package:solian/theme.dart';
|
import 'package:solian/theme.dart';
|
||||||
|
import 'package:solian/widgets/account/account_avatar.dart';
|
||||||
import 'package:solian/widgets/account/signin_required_overlay.dart';
|
import 'package:solian/widgets/account/signin_required_overlay.dart';
|
||||||
import 'package:solian/widgets/app_bar_leading.dart';
|
import 'package:solian/widgets/app_bar_leading.dart';
|
||||||
import 'package:solian/widgets/app_bar_title.dart';
|
import 'package:solian/widgets/app_bar_title.dart';
|
||||||
|
import 'package:solian/widgets/auto_cache_image.dart';
|
||||||
import 'package:solian/widgets/current_state_action.dart';
|
import 'package:solian/widgets/current_state_action.dart';
|
||||||
import 'package:solian/widgets/sized_container.dart';
|
import 'package:solian/widgets/sized_container.dart';
|
||||||
|
|
||||||
@ -128,18 +131,33 @@ class _RealmListScreenState extends State<RealmListScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
|
child: (element.banner?.isEmpty ?? true)
|
||||||
|
? const SizedBox.shrink()
|
||||||
|
: AutoCacheImage(
|
||||||
|
ServiceFinder.buildUrl(
|
||||||
|
'uc',
|
||||||
|
'/attachments/${element.banner}',
|
||||||
),
|
),
|
||||||
const Positioned(
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
bottom: -30,
|
bottom: -30,
|
||||||
left: 18,
|
left: 18,
|
||||||
child: CircleAvatar(
|
child: (element.avatar?.isEmpty ?? true)
|
||||||
|
? CircleAvatar(
|
||||||
radius: 24,
|
radius: 24,
|
||||||
backgroundColor: Colors.indigo,
|
backgroundColor:
|
||||||
child: FaIcon(
|
Theme.of(context).colorScheme.primary,
|
||||||
|
child: const FaIcon(
|
||||||
FontAwesomeIcons.globe,
|
FontAwesomeIcons.globe,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
: AccountAvatar(
|
||||||
|
content: element.avatar!,
|
||||||
|
bgColor: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -69,7 +69,8 @@ class _RealmDetailScreenState extends State<RealmDetailScreen> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.settings),
|
leading: const Icon(Icons.settings),
|
||||||
trailing: const Icon(Icons.chevron_right),
|
trailing: const Icon(Icons.chevron_right),
|
||||||
title: Text('realmSettings'.tr.capitalize!),
|
title: Text('realmSettings'.tr),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
AppRouter.instance
|
AppRouter.instance
|
||||||
.pushNamed(
|
.pushNamed(
|
||||||
@ -120,14 +121,16 @@ class _RealmDetailScreenState extends State<RealmDetailScreen> {
|
|||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
leading: const Icon(Icons.supervisor_account),
|
leading: const Icon(Icons.supervisor_account),
|
||||||
trailing: const Icon(Icons.chevron_right),
|
trailing: const Icon(Icons.chevron_right),
|
||||||
title: Text('realmMembers'.tr.capitalize!),
|
title: Text('realmMembers'.tr),
|
||||||
onTap: () => showMemberList(),
|
onTap: () => showMemberList(),
|
||||||
),
|
),
|
||||||
...(_isOwned ? ownerActions : List.empty()),
|
...(_isOwned ? ownerActions : List.empty()),
|
||||||
const Divider(thickness: 0.3),
|
const Divider(thickness: 0.3),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
leading: _isOwned
|
leading: _isOwned
|
||||||
? const Icon(Icons.delete)
|
? const Icon(Icons.delete)
|
||||||
: const Icon(Icons.exit_to_app),
|
: const Icon(Icons.exit_to_app),
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:image_cropper/image_cropper.dart';
|
||||||
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:solian/exts.dart';
|
import 'package:solian/exts.dart';
|
||||||
|
import 'package:solian/models/attachment.dart';
|
||||||
import 'package:solian/models/realm.dart';
|
import 'package:solian/models/realm.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
|
import 'package:solian/providers/content/attachment.dart';
|
||||||
import 'package:solian/router.dart';
|
import 'package:solian/router.dart';
|
||||||
import 'package:solian/theme.dart';
|
import 'package:solian/theme.dart';
|
||||||
import 'package:solian/widgets/app_bar_leading.dart';
|
import 'package:solian/widgets/app_bar_leading.dart';
|
||||||
@ -29,17 +35,19 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
bool _isBusy = false;
|
bool _isBusy = false;
|
||||||
|
|
||||||
final _aliasController = TextEditingController();
|
final _aliasController = TextEditingController();
|
||||||
|
final _avatarController = TextEditingController();
|
||||||
|
final _bannerController = TextEditingController();
|
||||||
final _nameController = TextEditingController();
|
final _nameController = TextEditingController();
|
||||||
final _descriptionController = TextEditingController();
|
final _descriptionController = TextEditingController();
|
||||||
|
|
||||||
bool _isCommunity = false;
|
bool _isCommunity = false;
|
||||||
bool _isPublic = false;
|
bool _isPublic = false;
|
||||||
|
|
||||||
void applyRealm() async {
|
void _applyRealm() async {
|
||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (auth.isAuthorized.isFalse) return;
|
if (auth.isAuthorized.isFalse) return;
|
||||||
|
|
||||||
if (_aliasController.value.text.isEmpty) randomizeAlias();
|
if (_aliasController.value.text.isEmpty) _randomizeAlias();
|
||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
@ -49,6 +57,8 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
'alias': _aliasController.value.text.toLowerCase(),
|
'alias': _aliasController.value.text.toLowerCase(),
|
||||||
'name': _nameController.value.text,
|
'name': _nameController.value.text,
|
||||||
'description': _descriptionController.value.text,
|
'description': _descriptionController.value.text,
|
||||||
|
'avatar': _avatarController.value.text,
|
||||||
|
'banner': _bannerController.value.text,
|
||||||
'is_public': _isPublic,
|
'is_public': _isPublic,
|
||||||
'is_community': _isCommunity,
|
'is_community': _isCommunity,
|
||||||
};
|
};
|
||||||
@ -68,31 +78,110 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void randomizeAlias() {
|
final _imagePicker = ImagePicker();
|
||||||
|
|
||||||
|
Future<void> _editImage(String position) async {
|
||||||
|
final AuthProvider auth = Get.find();
|
||||||
|
if (auth.isAuthorized.isFalse) return;
|
||||||
|
|
||||||
|
final image = await _imagePicker.pickImage(source: ImageSource.gallery);
|
||||||
|
if (image == null) return;
|
||||||
|
|
||||||
|
CroppedFile? croppedFile = await ImageCropper().cropImage(
|
||||||
|
sourcePath: image.path,
|
||||||
|
uiSettings: [
|
||||||
|
AndroidUiSettings(
|
||||||
|
toolbarTitle: 'cropImage'.tr,
|
||||||
|
toolbarColor: Theme.of(context).colorScheme.primary,
|
||||||
|
toolbarWidgetColor: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
aspectRatioPresets: [
|
||||||
|
if (position == 'avatar') CropAspectRatioPreset.square,
|
||||||
|
if (position == 'banner') _BannerCropAspectRatioPreset(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IOSUiSettings(
|
||||||
|
title: 'cropImage'.tr,
|
||||||
|
aspectRatioPresets: [
|
||||||
|
if (position == 'avatar') CropAspectRatioPreset.square,
|
||||||
|
if (position == 'banner') _BannerCropAspectRatioPreset(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
WebUiSettings(
|
||||||
|
context: context,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (croppedFile == null) return;
|
||||||
|
final file = File(croppedFile.path);
|
||||||
|
|
||||||
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
|
final AttachmentProvider attach = Get.find();
|
||||||
|
|
||||||
|
Attachment? attachResult;
|
||||||
|
try {
|
||||||
|
attachResult = await attach.createAttachmentDirectly(
|
||||||
|
await file.readAsBytes(),
|
||||||
|
file.path,
|
||||||
|
'avatar',
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
setState(() => _isBusy = false);
|
||||||
|
context.showErrorDialog(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (position) {
|
||||||
|
case 'avatar':
|
||||||
|
_avatarController.text = attachResult.rid;
|
||||||
|
break;
|
||||||
|
case 'banner':
|
||||||
|
_bannerController.text = attachResult.rid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() => _isBusy = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _randomizeAlias() {
|
||||||
_aliasController.text =
|
_aliasController.text =
|
||||||
const Uuid().v4().replaceAll('-', '').substring(0, 12);
|
const Uuid().v4().replaceAll('-', '').substring(0, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncWidget() {
|
void _syncWidget() {
|
||||||
if (widget.edit != null) {
|
if (widget.edit != null) {
|
||||||
_aliasController.text = widget.edit!.alias;
|
_aliasController.text = widget.edit!.alias;
|
||||||
_nameController.text = widget.edit!.name;
|
_nameController.text = widget.edit!.name;
|
||||||
_descriptionController.text = widget.edit!.description;
|
_descriptionController.text = widget.edit!.description;
|
||||||
|
_avatarController.text = widget.edit!.avatar ?? '';
|
||||||
|
_bannerController.text = widget.edit!.banner ?? '';
|
||||||
_isPublic = widget.edit!.isPublic;
|
_isPublic = widget.edit!.isPublic;
|
||||||
_isCommunity = widget.edit!.isCommunity;
|
_isCommunity = widget.edit!.isCommunity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cancelAction() {
|
void _cancelAction() {
|
||||||
AppRouter.instance.pop();
|
AppRouter.instance.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
syncWidget();
|
_syncWidget();
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_aliasController.dispose();
|
||||||
|
_avatarController.dispose();
|
||||||
|
_bannerController.dispose();
|
||||||
|
_nameController.dispose();
|
||||||
|
_descriptionController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Material(
|
return Material(
|
||||||
@ -105,7 +194,7 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
toolbarHeight: AppTheme.toolbarHeight(context),
|
toolbarHeight: AppTheme.toolbarHeight(context),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: _isBusy ? null : () => applyRealm(),
|
onPressed: _isBusy ? null : () => _applyRealm(),
|
||||||
child: Text('apply'.tr.toUpperCase()),
|
child: Text('apply'.tr.toUpperCase()),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -126,7 +215,7 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: cancelAction,
|
onPressed: _cancelAction,
|
||||||
child: Text('cancel'.tr),
|
child: Text('cancel'.tr),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -150,7 +239,7 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
visualDensity:
|
visualDensity:
|
||||||
const VisualDensity(horizontal: -2, vertical: -2),
|
const VisualDensity(horizontal: -2, vertical: -2),
|
||||||
),
|
),
|
||||||
onPressed: () => randomizeAlias(),
|
onPressed: () => _randomizeAlias(),
|
||||||
child: const Icon(Icons.refresh),
|
child: const Icon(Icons.refresh),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -166,6 +255,55 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
FocusManager.instance.primaryFocus?.unfocus(),
|
FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
).paddingSymmetric(horizontal: 16, vertical: 8),
|
).paddingSymmetric(horizontal: 16, vertical: 8),
|
||||||
const Divider(thickness: 0.3),
|
const Divider(thickness: 0.3),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TextField(
|
||||||
|
autofocus: true,
|
||||||
|
controller: _avatarController,
|
||||||
|
decoration: InputDecoration.collapsed(
|
||||||
|
hintText: 'realmAvatar'.tr,
|
||||||
|
),
|
||||||
|
onTapOutside: (_) =>
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
visualDensity:
|
||||||
|
const VisualDensity(horizontal: -2, vertical: -2),
|
||||||
|
),
|
||||||
|
onPressed: _isBusy ? null : () => _editImage('avatar'),
|
||||||
|
child: const Icon(Icons.upload),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
).paddingSymmetric(horizontal: 16, vertical: 2),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TextField(
|
||||||
|
autofocus: true,
|
||||||
|
controller: _bannerController,
|
||||||
|
decoration: InputDecoration.collapsed(
|
||||||
|
hintText: 'realmBanner'.tr,
|
||||||
|
),
|
||||||
|
onTapOutside: (_) =>
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
visualDensity:
|
||||||
|
const VisualDensity(horizontal: -2, vertical: -2),
|
||||||
|
),
|
||||||
|
onPressed: _isBusy ? null : () => _editImage('banner'),
|
||||||
|
child: const Icon(Icons.upload),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
).paddingSymmetric(horizontal: 16, vertical: 2),
|
||||||
|
const Divider(thickness: 0.3),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
minLines: 5,
|
minLines: 5,
|
||||||
@ -202,3 +340,11 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _BannerCropAspectRatioPreset extends CropAspectRatioPresetData {
|
||||||
|
@override
|
||||||
|
(int, int)? get data => (16, 7);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get name => '16x7';
|
||||||
|
}
|
||||||
|
@ -6,7 +6,9 @@ import 'package:solian/providers/auth.dart';
|
|||||||
import 'package:solian/providers/content/channel.dart';
|
import 'package:solian/providers/content/channel.dart';
|
||||||
import 'package:solian/providers/content/realm.dart';
|
import 'package:solian/providers/content/realm.dart';
|
||||||
import 'package:solian/providers/navigation.dart';
|
import 'package:solian/providers/navigation.dart';
|
||||||
|
import 'package:solian/services.dart';
|
||||||
import 'package:solian/widgets/account/account_avatar.dart';
|
import 'package:solian/widgets/account/account_avatar.dart';
|
||||||
|
import 'package:solian/widgets/auto_cache_image.dart';
|
||||||
import 'package:solian/widgets/channel/channel_list.dart';
|
import 'package:solian/widgets/channel/channel_list.dart';
|
||||||
|
|
||||||
class AppNavigationRegion extends StatefulWidget {
|
class AppNavigationRegion extends StatefulWidget {
|
||||||
@ -169,6 +171,19 @@ class _AppNavigationRegionState extends State<AppNavigationRegion> {
|
|||||||
)
|
)
|
||||||
: Column(
|
: Column(
|
||||||
children: [
|
children: [
|
||||||
|
if (!widget.isCollapsed &&
|
||||||
|
(navState.focusedRealm.value!.banner?.isNotEmpty ??
|
||||||
|
false))
|
||||||
|
AspectRatio(
|
||||||
|
aspectRatio: 16 / 7,
|
||||||
|
child: AutoCacheImage(
|
||||||
|
ServiceFinder.buildUrl(
|
||||||
|
'uc',
|
||||||
|
'/attachments/${navState.focusedRealm.value!.banner}',
|
||||||
|
),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
if (widget.isCollapsed)
|
if (widget.isCollapsed)
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: navState.focusedRealm.value!.name,
|
message: navState.focusedRealm.value!.name,
|
||||||
|
Loading…
Reference in New Issue
Block a user