✨ Chat room layout
This commit is contained in:
parent
cce0be4fb2
commit
63ec82891f
@ -70,5 +70,10 @@
|
|||||||
"name": "Name",
|
"name": "Name",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
"slug": "Slug",
|
"slug": "Slug",
|
||||||
"slugHint": "The slug will be used in the URL to access this resource, it should be unique and URL safe."
|
"slugHint": "The slug will be used in the URL to access this resource, it should be unique and URL safe.",
|
||||||
|
"createChatRoom": "Create a Room",
|
||||||
|
"editChatRoom": "Edit a Room",
|
||||||
|
"chat": "Chat",
|
||||||
|
"chatMessageHint": "Message in {}",
|
||||||
|
"chatDirectMessageHint": "Message to {}"
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ class AppRouter extends RootStackRouter {
|
|||||||
AutoRoute(page: ExploreRoute.page, path: 'explore'),
|
AutoRoute(page: ExploreRoute.page, path: 'explore'),
|
||||||
AutoRoute(page: AccountRoute.page, path: 'account'),
|
AutoRoute(page: AccountRoute.page, path: 'account'),
|
||||||
AutoRoute(page: RealmListRoute.page, path: 'realms'),
|
AutoRoute(page: RealmListRoute.page, path: 'realms'),
|
||||||
|
AutoRoute(page: ChatListRoute.page, path: 'chat'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
AutoRoute(page: LoginRoute.page, path: '/auth/login'),
|
AutoRoute(page: LoginRoute.page, path: '/auth/login'),
|
||||||
@ -33,5 +34,8 @@ class AppRouter extends RootStackRouter {
|
|||||||
AutoRoute(page: PostEditRoute.page, path: '/posts/:id/edit'),
|
AutoRoute(page: PostEditRoute.page, path: '/posts/:id/edit'),
|
||||||
AutoRoute(page: NewRealmRoute.page, path: '/realms/new'),
|
AutoRoute(page: NewRealmRoute.page, path: '/realms/new'),
|
||||||
AutoRoute(page: EditRealmRoute.page, path: '/realms/:slug/edit'),
|
AutoRoute(page: EditRealmRoute.page, path: '/realms/:slug/edit'),
|
||||||
|
AutoRoute(page: NewChatRoute.page, path: '/chat/new'),
|
||||||
|
AutoRoute(page: EditChatRoute.page, path: '/chat/:id/edit'),
|
||||||
|
AutoRoute(page: ChatRoomRoute.page, path: '/chat/:id'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -9,30 +9,32 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
|
|
||||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||||
import 'package:auto_route/auto_route.dart' as _i12;
|
import 'package:auto_route/auto_route.dart' as _i14;
|
||||||
import 'package:flutter/material.dart' as _i13;
|
import 'package:flutter/material.dart' as _i15;
|
||||||
import 'package:island/models/post.dart' as _i14;
|
import 'package:island/models/post.dart' as _i16;
|
||||||
import 'package:island/screens/account.dart' as _i1;
|
import 'package:island/screens/account.dart' as _i1;
|
||||||
import 'package:island/screens/account/me.dart' as _i7;
|
import 'package:island/screens/account/me.dart' as _i9;
|
||||||
import 'package:island/screens/account/me/publishers.dart' as _i3;
|
import 'package:island/screens/account/me/publishers.dart' as _i5;
|
||||||
import 'package:island/screens/account/me/update.dart' as _i11;
|
import 'package:island/screens/account/me/update.dart' as _i13;
|
||||||
import 'package:island/screens/auth/create_account.dart' as _i2;
|
import 'package:island/screens/auth/create_account.dart' as _i4;
|
||||||
import 'package:island/screens/auth/login.dart' as _i6;
|
import 'package:island/screens/auth/login.dart' as _i8;
|
||||||
import 'package:island/screens/auth/tabs.dart' as _i10;
|
import 'package:island/screens/auth/tabs.dart' as _i12;
|
||||||
import 'package:island/screens/explore.dart' as _i5;
|
import 'package:island/screens/chat/chat.dart' as _i2;
|
||||||
import 'package:island/screens/posts/compose.dart' as _i8;
|
import 'package:island/screens/chat/room.dart' as _i3;
|
||||||
import 'package:island/screens/posts/detail.dart' as _i9;
|
import 'package:island/screens/explore.dart' as _i7;
|
||||||
import 'package:island/screens/realm/realms.dart' as _i4;
|
import 'package:island/screens/posts/compose.dart' as _i10;
|
||||||
|
import 'package:island/screens/posts/detail.dart' as _i11;
|
||||||
|
import 'package:island/screens/realm/realms.dart' as _i6;
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i1.AccountScreen]
|
/// [_i1.AccountScreen]
|
||||||
class AccountRoute extends _i12.PageRouteInfo<void> {
|
class AccountRoute extends _i14.PageRouteInfo<void> {
|
||||||
const AccountRoute({List<_i12.PageRouteInfo>? children})
|
const AccountRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(AccountRoute.name, initialChildren: children);
|
: super(AccountRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'AccountRoute';
|
static const String name = 'AccountRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i1.AccountScreen();
|
return const _i1.AccountScreen();
|
||||||
@ -41,28 +43,123 @@ class AccountRoute extends _i12.PageRouteInfo<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i2.CreateAccountScreen]
|
/// [_i2.ChatListScreen]
|
||||||
class CreateAccountRoute extends _i12.PageRouteInfo<void> {
|
class ChatListRoute extends _i14.PageRouteInfo<void> {
|
||||||
const CreateAccountRoute({List<_i12.PageRouteInfo>? children})
|
const ChatListRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(CreateAccountRoute.name, initialChildren: children);
|
: super(ChatListRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'CreateAccountRoute';
|
static const String name = 'ChatListRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i2.CreateAccountScreen();
|
return const _i2.ChatListScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i3.EditPublisherScreen]
|
/// [_i3.ChatRoomScreen]
|
||||||
class EditPublisherRoute extends _i12.PageRouteInfo<EditPublisherRouteArgs> {
|
class ChatRoomRoute extends _i14.PageRouteInfo<ChatRoomRouteArgs> {
|
||||||
|
ChatRoomRoute({
|
||||||
|
_i15.Key? key,
|
||||||
|
required int id,
|
||||||
|
List<_i14.PageRouteInfo>? children,
|
||||||
|
}) : super(
|
||||||
|
ChatRoomRoute.name,
|
||||||
|
args: ChatRoomRouteArgs(key: key, id: id),
|
||||||
|
rawPathParams: {'id': id},
|
||||||
|
initialChildren: children,
|
||||||
|
);
|
||||||
|
|
||||||
|
static const String name = 'ChatRoomRoute';
|
||||||
|
|
||||||
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
|
name,
|
||||||
|
builder: (data) {
|
||||||
|
final pathParams = data.inheritedPathParams;
|
||||||
|
final args = data.argsAs<ChatRoomRouteArgs>(
|
||||||
|
orElse: () => ChatRoomRouteArgs(id: pathParams.getInt('id')),
|
||||||
|
);
|
||||||
|
return _i3.ChatRoomScreen(key: args.key, id: args.id);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChatRoomRouteArgs {
|
||||||
|
const ChatRoomRouteArgs({this.key, required this.id});
|
||||||
|
|
||||||
|
final _i15.Key? key;
|
||||||
|
|
||||||
|
final int id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ChatRoomRouteArgs{key: $key, id: $id}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [_i4.CreateAccountScreen]
|
||||||
|
class CreateAccountRoute extends _i14.PageRouteInfo<void> {
|
||||||
|
const CreateAccountRoute({List<_i14.PageRouteInfo>? children})
|
||||||
|
: super(CreateAccountRoute.name, initialChildren: children);
|
||||||
|
|
||||||
|
static const String name = 'CreateAccountRoute';
|
||||||
|
|
||||||
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
|
name,
|
||||||
|
builder: (data) {
|
||||||
|
return const _i4.CreateAccountScreen();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [_i2.EditChatScreen]
|
||||||
|
class EditChatRoute extends _i14.PageRouteInfo<EditChatRouteArgs> {
|
||||||
|
EditChatRoute({_i15.Key? key, int? id, List<_i14.PageRouteInfo>? children})
|
||||||
|
: super(
|
||||||
|
EditChatRoute.name,
|
||||||
|
args: EditChatRouteArgs(key: key, id: id),
|
||||||
|
rawPathParams: {'id': id},
|
||||||
|
initialChildren: children,
|
||||||
|
);
|
||||||
|
|
||||||
|
static const String name = 'EditChatRoute';
|
||||||
|
|
||||||
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
|
name,
|
||||||
|
builder: (data) {
|
||||||
|
final pathParams = data.inheritedPathParams;
|
||||||
|
final args = data.argsAs<EditChatRouteArgs>(
|
||||||
|
orElse: () => EditChatRouteArgs(id: pathParams.optInt('id')),
|
||||||
|
);
|
||||||
|
return _i2.EditChatScreen(key: args.key, id: args.id);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditChatRouteArgs {
|
||||||
|
const EditChatRouteArgs({this.key, this.id});
|
||||||
|
|
||||||
|
final _i15.Key? key;
|
||||||
|
|
||||||
|
final int? id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'EditChatRouteArgs{key: $key, id: $id}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [_i5.EditPublisherScreen]
|
||||||
|
class EditPublisherRoute extends _i14.PageRouteInfo<EditPublisherRouteArgs> {
|
||||||
EditPublisherRoute({
|
EditPublisherRoute({
|
||||||
_i13.Key? key,
|
_i15.Key? key,
|
||||||
String? name,
|
String? name,
|
||||||
List<_i12.PageRouteInfo>? children,
|
List<_i14.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
EditPublisherRoute.name,
|
EditPublisherRoute.name,
|
||||||
args: EditPublisherRouteArgs(key: key, name: name),
|
args: EditPublisherRouteArgs(key: key, name: name),
|
||||||
@ -72,14 +169,14 @@ class EditPublisherRoute extends _i12.PageRouteInfo<EditPublisherRouteArgs> {
|
|||||||
|
|
||||||
static const String name = 'EditPublisherRoute';
|
static const String name = 'EditPublisherRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final pathParams = data.inheritedPathParams;
|
final pathParams = data.inheritedPathParams;
|
||||||
final args = data.argsAs<EditPublisherRouteArgs>(
|
final args = data.argsAs<EditPublisherRouteArgs>(
|
||||||
orElse: () => EditPublisherRouteArgs(name: pathParams.optString('id')),
|
orElse: () => EditPublisherRouteArgs(name: pathParams.optString('id')),
|
||||||
);
|
);
|
||||||
return _i3.EditPublisherScreen(key: args.key, name: args.name);
|
return _i5.EditPublisherScreen(key: args.key, name: args.name);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -87,7 +184,7 @@ class EditPublisherRoute extends _i12.PageRouteInfo<EditPublisherRouteArgs> {
|
|||||||
class EditPublisherRouteArgs {
|
class EditPublisherRouteArgs {
|
||||||
const EditPublisherRouteArgs({this.key, this.name});
|
const EditPublisherRouteArgs({this.key, this.name});
|
||||||
|
|
||||||
final _i13.Key? key;
|
final _i15.Key? key;
|
||||||
|
|
||||||
final String? name;
|
final String? name;
|
||||||
|
|
||||||
@ -98,12 +195,12 @@ class EditPublisherRouteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i4.EditRealmScreen]
|
/// [_i6.EditRealmScreen]
|
||||||
class EditRealmRoute extends _i12.PageRouteInfo<EditRealmRouteArgs> {
|
class EditRealmRoute extends _i14.PageRouteInfo<EditRealmRouteArgs> {
|
||||||
EditRealmRoute({
|
EditRealmRoute({
|
||||||
_i13.Key? key,
|
_i15.Key? key,
|
||||||
String? slug,
|
String? slug,
|
||||||
List<_i12.PageRouteInfo>? children,
|
List<_i14.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
EditRealmRoute.name,
|
EditRealmRoute.name,
|
||||||
args: EditRealmRouteArgs(key: key, slug: slug),
|
args: EditRealmRouteArgs(key: key, slug: slug),
|
||||||
@ -113,14 +210,14 @@ class EditRealmRoute extends _i12.PageRouteInfo<EditRealmRouteArgs> {
|
|||||||
|
|
||||||
static const String name = 'EditRealmRoute';
|
static const String name = 'EditRealmRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final pathParams = data.inheritedPathParams;
|
final pathParams = data.inheritedPathParams;
|
||||||
final args = data.argsAs<EditRealmRouteArgs>(
|
final args = data.argsAs<EditRealmRouteArgs>(
|
||||||
orElse: () => EditRealmRouteArgs(slug: pathParams.optString('slug')),
|
orElse: () => EditRealmRouteArgs(slug: pathParams.optString('slug')),
|
||||||
);
|
);
|
||||||
return _i4.EditRealmScreen(key: args.key, slug: args.slug);
|
return _i6.EditRealmScreen(key: args.key, slug: args.slug);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -128,7 +225,7 @@ class EditRealmRoute extends _i12.PageRouteInfo<EditRealmRouteArgs> {
|
|||||||
class EditRealmRouteArgs {
|
class EditRealmRouteArgs {
|
||||||
const EditRealmRouteArgs({this.key, this.slug});
|
const EditRealmRouteArgs({this.key, this.slug});
|
||||||
|
|
||||||
final _i13.Key? key;
|
final _i15.Key? key;
|
||||||
|
|
||||||
final String? slug;
|
final String? slug;
|
||||||
|
|
||||||
@ -139,108 +236,124 @@ class EditRealmRouteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i5.ExploreScreen]
|
/// [_i7.ExploreScreen]
|
||||||
class ExploreRoute extends _i12.PageRouteInfo<void> {
|
class ExploreRoute extends _i14.PageRouteInfo<void> {
|
||||||
const ExploreRoute({List<_i12.PageRouteInfo>? children})
|
const ExploreRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(ExploreRoute.name, initialChildren: children);
|
: super(ExploreRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'ExploreRoute';
|
static const String name = 'ExploreRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i5.ExploreScreen();
|
return const _i7.ExploreScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i6.LoginScreen]
|
/// [_i8.LoginScreen]
|
||||||
class LoginRoute extends _i12.PageRouteInfo<void> {
|
class LoginRoute extends _i14.PageRouteInfo<void> {
|
||||||
const LoginRoute({List<_i12.PageRouteInfo>? children})
|
const LoginRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(LoginRoute.name, initialChildren: children);
|
: super(LoginRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'LoginRoute';
|
static const String name = 'LoginRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i6.LoginScreen();
|
return const _i8.LoginScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i3.ManagedPublisherScreen]
|
/// [_i5.ManagedPublisherScreen]
|
||||||
class ManagedPublisherRoute extends _i12.PageRouteInfo<void> {
|
class ManagedPublisherRoute extends _i14.PageRouteInfo<void> {
|
||||||
const ManagedPublisherRoute({List<_i12.PageRouteInfo>? children})
|
const ManagedPublisherRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(ManagedPublisherRoute.name, initialChildren: children);
|
: super(ManagedPublisherRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'ManagedPublisherRoute';
|
static const String name = 'ManagedPublisherRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i3.ManagedPublisherScreen();
|
return const _i5.ManagedPublisherScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i7.MyselfProfileScreen]
|
/// [_i9.MyselfProfileScreen]
|
||||||
class MyselfProfileRoute extends _i12.PageRouteInfo<void> {
|
class MyselfProfileRoute extends _i14.PageRouteInfo<void> {
|
||||||
const MyselfProfileRoute({List<_i12.PageRouteInfo>? children})
|
const MyselfProfileRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(MyselfProfileRoute.name, initialChildren: children);
|
: super(MyselfProfileRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'MyselfProfileRoute';
|
static const String name = 'MyselfProfileRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i7.MyselfProfileScreen();
|
return const _i9.MyselfProfileScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i3.NewPublisherScreen]
|
/// [_i2.NewChatScreen]
|
||||||
class NewPublisherRoute extends _i12.PageRouteInfo<void> {
|
class NewChatRoute extends _i14.PageRouteInfo<void> {
|
||||||
const NewPublisherRoute({List<_i12.PageRouteInfo>? children})
|
const NewChatRoute({List<_i14.PageRouteInfo>? children})
|
||||||
|
: super(NewChatRoute.name, initialChildren: children);
|
||||||
|
|
||||||
|
static const String name = 'NewChatRoute';
|
||||||
|
|
||||||
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
|
name,
|
||||||
|
builder: (data) {
|
||||||
|
return const _i2.NewChatScreen();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [_i5.NewPublisherScreen]
|
||||||
|
class NewPublisherRoute extends _i14.PageRouteInfo<void> {
|
||||||
|
const NewPublisherRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(NewPublisherRoute.name, initialChildren: children);
|
: super(NewPublisherRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'NewPublisherRoute';
|
static const String name = 'NewPublisherRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i3.NewPublisherScreen();
|
return const _i5.NewPublisherScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i4.NewRealmScreen]
|
/// [_i6.NewRealmScreen]
|
||||||
class NewRealmRoute extends _i12.PageRouteInfo<void> {
|
class NewRealmRoute extends _i14.PageRouteInfo<void> {
|
||||||
const NewRealmRoute({List<_i12.PageRouteInfo>? children})
|
const NewRealmRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(NewRealmRoute.name, initialChildren: children);
|
: super(NewRealmRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'NewRealmRoute';
|
static const String name = 'NewRealmRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i4.NewRealmScreen();
|
return const _i6.NewRealmScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i8.PostComposeScreen]
|
/// [_i10.PostComposeScreen]
|
||||||
class PostComposeRoute extends _i12.PageRouteInfo<PostComposeRouteArgs> {
|
class PostComposeRoute extends _i14.PageRouteInfo<PostComposeRouteArgs> {
|
||||||
PostComposeRoute({
|
PostComposeRoute({
|
||||||
_i13.Key? key,
|
_i15.Key? key,
|
||||||
_i14.SnPost? originalPost,
|
_i16.SnPost? originalPost,
|
||||||
List<_i12.PageRouteInfo>? children,
|
List<_i14.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
PostComposeRoute.name,
|
PostComposeRoute.name,
|
||||||
args: PostComposeRouteArgs(key: key, originalPost: originalPost),
|
args: PostComposeRouteArgs(key: key, originalPost: originalPost),
|
||||||
@ -249,13 +362,13 @@ class PostComposeRoute extends _i12.PageRouteInfo<PostComposeRouteArgs> {
|
|||||||
|
|
||||||
static const String name = 'PostComposeRoute';
|
static const String name = 'PostComposeRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final args = data.argsAs<PostComposeRouteArgs>(
|
final args = data.argsAs<PostComposeRouteArgs>(
|
||||||
orElse: () => const PostComposeRouteArgs(),
|
orElse: () => const PostComposeRouteArgs(),
|
||||||
);
|
);
|
||||||
return _i8.PostComposeScreen(
|
return _i10.PostComposeScreen(
|
||||||
key: args.key,
|
key: args.key,
|
||||||
originalPost: args.originalPost,
|
originalPost: args.originalPost,
|
||||||
);
|
);
|
||||||
@ -266,9 +379,9 @@ class PostComposeRoute extends _i12.PageRouteInfo<PostComposeRouteArgs> {
|
|||||||
class PostComposeRouteArgs {
|
class PostComposeRouteArgs {
|
||||||
const PostComposeRouteArgs({this.key, this.originalPost});
|
const PostComposeRouteArgs({this.key, this.originalPost});
|
||||||
|
|
||||||
final _i13.Key? key;
|
final _i15.Key? key;
|
||||||
|
|
||||||
final _i14.SnPost? originalPost;
|
final _i16.SnPost? originalPost;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
@ -277,12 +390,12 @@ class PostComposeRouteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i9.PostDetailScreen]
|
/// [_i11.PostDetailScreen]
|
||||||
class PostDetailRoute extends _i12.PageRouteInfo<PostDetailRouteArgs> {
|
class PostDetailRoute extends _i14.PageRouteInfo<PostDetailRouteArgs> {
|
||||||
PostDetailRoute({
|
PostDetailRoute({
|
||||||
_i13.Key? key,
|
_i15.Key? key,
|
||||||
required int id,
|
required int id,
|
||||||
List<_i12.PageRouteInfo>? children,
|
List<_i14.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
PostDetailRoute.name,
|
PostDetailRoute.name,
|
||||||
args: PostDetailRouteArgs(key: key, id: id),
|
args: PostDetailRouteArgs(key: key, id: id),
|
||||||
@ -292,14 +405,14 @@ class PostDetailRoute extends _i12.PageRouteInfo<PostDetailRouteArgs> {
|
|||||||
|
|
||||||
static const String name = 'PostDetailRoute';
|
static const String name = 'PostDetailRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final pathParams = data.inheritedPathParams;
|
final pathParams = data.inheritedPathParams;
|
||||||
final args = data.argsAs<PostDetailRouteArgs>(
|
final args = data.argsAs<PostDetailRouteArgs>(
|
||||||
orElse: () => PostDetailRouteArgs(id: pathParams.getInt('id')),
|
orElse: () => PostDetailRouteArgs(id: pathParams.getInt('id')),
|
||||||
);
|
);
|
||||||
return _i9.PostDetailScreen(key: args.key, id: args.id);
|
return _i11.PostDetailScreen(key: args.key, id: args.id);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -307,7 +420,7 @@ class PostDetailRoute extends _i12.PageRouteInfo<PostDetailRouteArgs> {
|
|||||||
class PostDetailRouteArgs {
|
class PostDetailRouteArgs {
|
||||||
const PostDetailRouteArgs({this.key, required this.id});
|
const PostDetailRouteArgs({this.key, required this.id});
|
||||||
|
|
||||||
final _i13.Key? key;
|
final _i15.Key? key;
|
||||||
|
|
||||||
final int id;
|
final int id;
|
||||||
|
|
||||||
@ -318,12 +431,12 @@ class PostDetailRouteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i8.PostEditScreen]
|
/// [_i10.PostEditScreen]
|
||||||
class PostEditRoute extends _i12.PageRouteInfo<PostEditRouteArgs> {
|
class PostEditRoute extends _i14.PageRouteInfo<PostEditRouteArgs> {
|
||||||
PostEditRoute({
|
PostEditRoute({
|
||||||
_i13.Key? key,
|
_i15.Key? key,
|
||||||
required int id,
|
required int id,
|
||||||
List<_i12.PageRouteInfo>? children,
|
List<_i14.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
PostEditRoute.name,
|
PostEditRoute.name,
|
||||||
args: PostEditRouteArgs(key: key, id: id),
|
args: PostEditRouteArgs(key: key, id: id),
|
||||||
@ -333,14 +446,14 @@ class PostEditRoute extends _i12.PageRouteInfo<PostEditRouteArgs> {
|
|||||||
|
|
||||||
static const String name = 'PostEditRoute';
|
static const String name = 'PostEditRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final pathParams = data.inheritedPathParams;
|
final pathParams = data.inheritedPathParams;
|
||||||
final args = data.argsAs<PostEditRouteArgs>(
|
final args = data.argsAs<PostEditRouteArgs>(
|
||||||
orElse: () => PostEditRouteArgs(id: pathParams.getInt('id')),
|
orElse: () => PostEditRouteArgs(id: pathParams.getInt('id')),
|
||||||
);
|
);
|
||||||
return _i8.PostEditScreen(key: args.key, id: args.id);
|
return _i10.PostEditScreen(key: args.key, id: args.id);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -348,7 +461,7 @@ class PostEditRoute extends _i12.PageRouteInfo<PostEditRouteArgs> {
|
|||||||
class PostEditRouteArgs {
|
class PostEditRouteArgs {
|
||||||
const PostEditRouteArgs({this.key, required this.id});
|
const PostEditRouteArgs({this.key, required this.id});
|
||||||
|
|
||||||
final _i13.Key? key;
|
final _i15.Key? key;
|
||||||
|
|
||||||
final int id;
|
final int id;
|
||||||
|
|
||||||
@ -359,49 +472,49 @@ class PostEditRouteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i4.RealmListScreen]
|
/// [_i6.RealmListScreen]
|
||||||
class RealmListRoute extends _i12.PageRouteInfo<void> {
|
class RealmListRoute extends _i14.PageRouteInfo<void> {
|
||||||
const RealmListRoute({List<_i12.PageRouteInfo>? children})
|
const RealmListRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(RealmListRoute.name, initialChildren: children);
|
: super(RealmListRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'RealmListRoute';
|
static const String name = 'RealmListRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i4.RealmListScreen();
|
return const _i6.RealmListScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i10.TabsScreen]
|
/// [_i12.TabsScreen]
|
||||||
class TabsRoute extends _i12.PageRouteInfo<void> {
|
class TabsRoute extends _i14.PageRouteInfo<void> {
|
||||||
const TabsRoute({List<_i12.PageRouteInfo>? children})
|
const TabsRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(TabsRoute.name, initialChildren: children);
|
: super(TabsRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'TabsRoute';
|
static const String name = 'TabsRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i10.TabsScreen();
|
return const _i12.TabsScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i11.UpdateProfileScreen]
|
/// [_i13.UpdateProfileScreen]
|
||||||
class UpdateProfileRoute extends _i12.PageRouteInfo<void> {
|
class UpdateProfileRoute extends _i14.PageRouteInfo<void> {
|
||||||
const UpdateProfileRoute({List<_i12.PageRouteInfo>? children})
|
const UpdateProfileRoute({List<_i14.PageRouteInfo>? children})
|
||||||
: super(UpdateProfileRoute.name, initialChildren: children);
|
: super(UpdateProfileRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'UpdateProfileRoute';
|
static const String name = 'UpdateProfileRoute';
|
||||||
|
|
||||||
static _i12.PageInfo page = _i12.PageInfo(
|
static _i14.PageInfo page = _i14.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i11.UpdateProfileScreen();
|
return const _i13.UpdateProfileScreen();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,12 @@ class TabsScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AutoTabsRouter.pageView(
|
return AutoTabsRouter.pageView(
|
||||||
routes: const [ExploreRoute(), RealmListRoute(), AccountRoute()],
|
routes: const [
|
||||||
|
ExploreRoute(),
|
||||||
|
ChatListRoute(),
|
||||||
|
RealmListRoute(),
|
||||||
|
AccountRoute(),
|
||||||
|
],
|
||||||
builder: (context, child, _) {
|
builder: (context, child, _) {
|
||||||
final tabsRouter = AutoTabsRouter.of(context);
|
final tabsRouter = AutoTabsRouter.of(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -26,6 +31,10 @@ class TabsScreen extends StatelessWidget {
|
|||||||
label: 'explore'.tr(),
|
label: 'explore'.tr(),
|
||||||
icon: const Icon(Symbols.explore),
|
icon: const Icon(Symbols.explore),
|
||||||
),
|
),
|
||||||
|
NavigationDestination(
|
||||||
|
label: 'chat'.tr(),
|
||||||
|
icon: const Icon(Symbols.chat),
|
||||||
|
),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
label: 'realms'.tr(),
|
label: 'realms'.tr(),
|
||||||
icon: const Icon(Symbols.workspaces),
|
icon: const Icon(Symbols.workspaces),
|
||||||
|
276
lib/screens/chat/chat.dart
Normal file
276
lib/screens/chat/chat.dart
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:island/models/chat.dart';
|
||||||
|
import 'package:island/models/file.dart';
|
||||||
|
import 'package:island/pods/config.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/route.gr.dart';
|
||||||
|
import 'package:island/services/file.dart';
|
||||||
|
import 'package:island/widgets/alert.dart';
|
||||||
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
|
part 'chat.g.dart';
|
||||||
|
|
||||||
|
@riverpod
|
||||||
|
Future<List<SnChat>> chatroomsJoined(Ref ref) async {
|
||||||
|
final client = ref.watch(apiClientProvider);
|
||||||
|
final resp = await client.get('/chat');
|
||||||
|
return resp.data.map((e) => SnChat.fromJson(e)).cast<SnChat>().toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class ChatListScreen extends HookConsumerWidget {
|
||||||
|
const ChatListScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final chats = ref.watch(chatroomsJoinedProvider);
|
||||||
|
|
||||||
|
return AppScaffold(
|
||||||
|
appBar: AppBar(title: Text('chat').tr()),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.pushRoute(NewChatRoute());
|
||||||
|
},
|
||||||
|
child: const Icon(Symbols.add),
|
||||||
|
),
|
||||||
|
body: chats.when(
|
||||||
|
data:
|
||||||
|
(items) => RefreshIndicator(
|
||||||
|
onRefresh:
|
||||||
|
() => Future.sync(() {
|
||||||
|
ref.invalidate(chatroomsJoinedProvider);
|
||||||
|
}),
|
||||||
|
child: ListView.builder(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
itemCount: items.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final item = items[index];
|
||||||
|
return ListTile(
|
||||||
|
leading:
|
||||||
|
item.picture == null
|
||||||
|
? CircleAvatar(
|
||||||
|
child: Text(item.name[0].toUpperCase()),
|
||||||
|
)
|
||||||
|
: ProfilePictureWidget(item: item.picture),
|
||||||
|
title: Text(item.name),
|
||||||
|
subtitle: Text(item.description),
|
||||||
|
onTap: () {
|
||||||
|
context.pushRoute(ChatRoomRoute(id: item.id));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
|
error: (error, stack) => Center(child: Text('Error: $error')),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@riverpod
|
||||||
|
Future<SnChat?> chatroom(Ref ref, int? identifier) async {
|
||||||
|
if (identifier == null) return null;
|
||||||
|
final client = ref.watch(apiClientProvider);
|
||||||
|
final resp = await client.get('/chat/$identifier');
|
||||||
|
return SnChat.fromJson(resp.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class NewChatScreen extends StatelessWidget {
|
||||||
|
const NewChatScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return EditChatScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class EditChatScreen extends HookConsumerWidget {
|
||||||
|
final int? id;
|
||||||
|
const EditChatScreen({super.key, @PathParam("id") this.id});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final formKey = useMemoized(() => GlobalKey<FormState>(), []);
|
||||||
|
|
||||||
|
final submitting = useState(false);
|
||||||
|
|
||||||
|
final nameController = useTextEditingController();
|
||||||
|
final descriptionController = useTextEditingController();
|
||||||
|
final picture = useState<SnCloudFile?>(null);
|
||||||
|
final background = useState<SnCloudFile?>(null);
|
||||||
|
|
||||||
|
final chat = ref.watch(chatroomProvider(id));
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
if (chat.value != null) {
|
||||||
|
nameController.text = chat.value!.name;
|
||||||
|
descriptionController.text = chat.value!.description;
|
||||||
|
picture.value = chat.value!.picture;
|
||||||
|
background.value = chat.value!.background;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}, [chat]);
|
||||||
|
|
||||||
|
void setPicture(String position) async {
|
||||||
|
final result = await ref
|
||||||
|
.read(imagePickerProvider)
|
||||||
|
.pickImage(source: ImageSource.gallery);
|
||||||
|
if (result == null) return;
|
||||||
|
|
||||||
|
submitting.value = true;
|
||||||
|
try {
|
||||||
|
final baseUrl = ref.watch(serverUrlProvider);
|
||||||
|
final atk = await getFreshAtk(
|
||||||
|
ref.watch(tokenPairProvider),
|
||||||
|
baseUrl,
|
||||||
|
onRefreshed: (atk, rtk) {
|
||||||
|
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
||||||
|
ref.invalidate(tokenPairProvider);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (atk == null) throw ArgumentError('Access token is null');
|
||||||
|
final cloudFile =
|
||||||
|
await putMediaToCloud(
|
||||||
|
fileData: result,
|
||||||
|
atk: atk,
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
filename: result.name,
|
||||||
|
mimetype: result.mimeType ?? 'image/jpeg',
|
||||||
|
).future;
|
||||||
|
if (cloudFile == null) {
|
||||||
|
throw ArgumentError('Failed to upload the file...');
|
||||||
|
}
|
||||||
|
switch (position) {
|
||||||
|
case 'picture':
|
||||||
|
picture.value = cloudFile;
|
||||||
|
case 'background':
|
||||||
|
background.value = cloudFile;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
} finally {
|
||||||
|
submitting.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> performAction() async {
|
||||||
|
if (!formKey.currentState!.validate()) return;
|
||||||
|
|
||||||
|
submitting.value = true;
|
||||||
|
try {
|
||||||
|
final client = ref.watch(apiClientProvider);
|
||||||
|
final resp = await client.request(
|
||||||
|
id == null ? '/chat' : '/chat/$id',
|
||||||
|
data: {
|
||||||
|
'name': nameController.text,
|
||||||
|
'description': descriptionController.text,
|
||||||
|
'background_id': background.value?.id,
|
||||||
|
'picture_id': picture.value?.id,
|
||||||
|
},
|
||||||
|
options: Options(method: id == null ? 'POST' : 'PATCH'),
|
||||||
|
);
|
||||||
|
if (context.mounted) {
|
||||||
|
context.maybePop(SnChat.fromJson(resp.data));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
} finally {
|
||||||
|
submitting.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AppScaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(id == null ? 'createChatRoom' : 'editChatRoom').tr(),
|
||||||
|
leading: const PageBackButton(),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
AspectRatio(
|
||||||
|
aspectRatio: 16 / 7,
|
||||||
|
child: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
child: Container(
|
||||||
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
|
child:
|
||||||
|
background.value != null
|
||||||
|
? CloudFileWidget(
|
||||||
|
item: background.value!,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
setPicture('background');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 20,
|
||||||
|
bottom: -32,
|
||||||
|
child: GestureDetector(
|
||||||
|
child: ProfilePictureWidget(
|
||||||
|
item: picture.value,
|
||||||
|
radius: 40,
|
||||||
|
fallbackIcon: Symbols.group,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
setPicture('picture');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
).padding(bottom: 32),
|
||||||
|
Form(
|
||||||
|
key: formKey,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
controller: nameController,
|
||||||
|
decoration: const InputDecoration(labelText: 'Name'),
|
||||||
|
onTapOutside:
|
||||||
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
TextFormField(
|
||||||
|
controller: descriptionController,
|
||||||
|
decoration: const InputDecoration(labelText: 'Description'),
|
||||||
|
minLines: 3,
|
||||||
|
maxLines: null,
|
||||||
|
onTapOutside:
|
||||||
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: TextButton.icon(
|
||||||
|
onPressed: submitting.value ? null : performAction,
|
||||||
|
label: const Text('Save'),
|
||||||
|
icon: const Icon(Symbols.save),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(all: 24),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
167
lib/screens/chat/chat.g.dart
Normal file
167
lib/screens/chat/chat.g.dart
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'chat.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// RiverpodGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
String _$chatroomsJoinedHash() => r'3a2db4159663c54dfd7bc40519e2faa6df69b41f';
|
||||||
|
|
||||||
|
/// See also [chatroomsJoined].
|
||||||
|
@ProviderFor(chatroomsJoined)
|
||||||
|
final chatroomsJoinedProvider =
|
||||||
|
AutoDisposeFutureProvider<List<SnChat>>.internal(
|
||||||
|
chatroomsJoined,
|
||||||
|
name: r'chatroomsJoinedProvider',
|
||||||
|
debugGetCreateSourceHash:
|
||||||
|
const bool.fromEnvironment('dart.vm.product')
|
||||||
|
? null
|
||||||
|
: _$chatroomsJoinedHash,
|
||||||
|
dependencies: null,
|
||||||
|
allTransitiveDependencies: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
|
// ignore: unused_element
|
||||||
|
typedef ChatroomsJoinedRef = AutoDisposeFutureProviderRef<List<SnChat>>;
|
||||||
|
String _$chatroomHash() => r'27bd4cb49326bb2f2eac7d7db9db7f610e21afb2';
|
||||||
|
|
||||||
|
/// Copied from Dart SDK
|
||||||
|
class _SystemHash {
|
||||||
|
_SystemHash._();
|
||||||
|
|
||||||
|
static int combine(int hash, int value) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + value);
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||||
|
return hash ^ (hash >> 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int finish(int hash) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = hash ^ (hash >> 11);
|
||||||
|
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See also [chatroom].
|
||||||
|
@ProviderFor(chatroom)
|
||||||
|
const chatroomProvider = ChatroomFamily();
|
||||||
|
|
||||||
|
/// See also [chatroom].
|
||||||
|
class ChatroomFamily extends Family<AsyncValue<SnChat?>> {
|
||||||
|
/// See also [chatroom].
|
||||||
|
const ChatroomFamily();
|
||||||
|
|
||||||
|
/// See also [chatroom].
|
||||||
|
ChatroomProvider call(int? identifier) {
|
||||||
|
return ChatroomProvider(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ChatroomProvider getProviderOverride(covariant ChatroomProvider provider) {
|
||||||
|
return call(provider.identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||||
|
_allTransitiveDependencies;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get name => r'chatroomProvider';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See also [chatroom].
|
||||||
|
class ChatroomProvider extends AutoDisposeFutureProvider<SnChat?> {
|
||||||
|
/// See also [chatroom].
|
||||||
|
ChatroomProvider(int? identifier)
|
||||||
|
: this._internal(
|
||||||
|
(ref) => chatroom(ref as ChatroomRef, identifier),
|
||||||
|
from: chatroomProvider,
|
||||||
|
name: r'chatroomProvider',
|
||||||
|
debugGetCreateSourceHash:
|
||||||
|
const bool.fromEnvironment('dart.vm.product')
|
||||||
|
? null
|
||||||
|
: _$chatroomHash,
|
||||||
|
dependencies: ChatroomFamily._dependencies,
|
||||||
|
allTransitiveDependencies: ChatroomFamily._allTransitiveDependencies,
|
||||||
|
identifier: identifier,
|
||||||
|
);
|
||||||
|
|
||||||
|
ChatroomProvider._internal(
|
||||||
|
super._createNotifier, {
|
||||||
|
required super.name,
|
||||||
|
required super.dependencies,
|
||||||
|
required super.allTransitiveDependencies,
|
||||||
|
required super.debugGetCreateSourceHash,
|
||||||
|
required super.from,
|
||||||
|
required this.identifier,
|
||||||
|
}) : super.internal();
|
||||||
|
|
||||||
|
final int? identifier;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Override overrideWith(
|
||||||
|
FutureOr<SnChat?> Function(ChatroomRef provider) create,
|
||||||
|
) {
|
||||||
|
return ProviderOverride(
|
||||||
|
origin: this,
|
||||||
|
override: ChatroomProvider._internal(
|
||||||
|
(ref) => create(ref as ChatroomRef),
|
||||||
|
from: from,
|
||||||
|
name: null,
|
||||||
|
dependencies: null,
|
||||||
|
allTransitiveDependencies: null,
|
||||||
|
debugGetCreateSourceHash: null,
|
||||||
|
identifier: identifier,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
AutoDisposeFutureProviderElement<SnChat?> createElement() {
|
||||||
|
return _ChatroomProviderElement(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is ChatroomProvider && other.identifier == identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||||
|
hash = _SystemHash.combine(hash, identifier.hashCode);
|
||||||
|
|
||||||
|
return _SystemHash.finish(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
|
// ignore: unused_element
|
||||||
|
mixin ChatroomRef on AutoDisposeFutureProviderRef<SnChat?> {
|
||||||
|
/// The parameter `identifier` of this provider.
|
||||||
|
int? get identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ChatroomProviderElement extends AutoDisposeFutureProviderElement<SnChat?>
|
||||||
|
with ChatroomRef {
|
||||||
|
_ChatroomProviderElement(super.provider);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int? get identifier => (origin as ChatroomProvider).identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
0
lib/screens/chat/new_chat.dart
Normal file
0
lib/screens/chat/new_chat.dart
Normal file
118
lib/screens/chat/room.dart
Normal file
118
lib/screens/chat/room.dart
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import 'package:auto_route/annotations.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
import 'chat.dart';
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class ChatRoomScreen extends HookConsumerWidget {
|
||||||
|
final int id;
|
||||||
|
const ChatRoomScreen({super.key, @PathParam("id") required this.id});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final chatRoom = ref.watch(chatroomProvider(id));
|
||||||
|
|
||||||
|
final messageController = useTextEditingController();
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: chatRoom.when(
|
||||||
|
data:
|
||||||
|
(room) => Row(
|
||||||
|
spacing: 8,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 26,
|
||||||
|
width: 26,
|
||||||
|
child:
|
||||||
|
room?.picture != null
|
||||||
|
? ProfilePictureWidget(
|
||||||
|
item: room?.picture,
|
||||||
|
fallbackIcon: Symbols.chat,
|
||||||
|
)
|
||||||
|
: CircleAvatar(
|
||||||
|
child: Text(
|
||||||
|
room?.name[0].toUpperCase() ?? '',
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(room?.name ?? 'unknown').fontSize(19).tr(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
loading: () => const Text('Loading...'),
|
||||||
|
error: (_, __) => const Text('Error'),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
IconButton(icon: const Icon(Icons.more_vert), onPressed: () {}),
|
||||||
|
const Gap(8),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: chatRoom.when(
|
||||||
|
data: (room) => SizedBox.expand(),
|
||||||
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
|
error: (error, stack) => Center(child: Text('Error: $error')),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Material(
|
||||||
|
elevation: 2,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.2),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 3,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
IconButton(icon: const Icon(Icons.add), onPressed: () {}),
|
||||||
|
Expanded(
|
||||||
|
child: TextField(
|
||||||
|
controller: messageController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'chatMessageHint'.tr(
|
||||||
|
args: [chatRoom.value?.name ?? 'unknown'.tr()],
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 12,
|
||||||
|
vertical: 8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
maxLines: null,
|
||||||
|
onTapOutside:
|
||||||
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.send),
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(bottom: MediaQuery.of(context).padding.bottom),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user