Compare commits
5 Commits
9f9c90abc4
...
2.2.2+56
| Author | SHA1 | Date | |
|---|---|---|---|
| a355e3bf90 | |||
| cb4a2598c8 | |||
| 950612dc07 | |||
| cbd1eaf1af | |||
| ac41cbd99f |
@@ -196,6 +196,10 @@
|
|||||||
"settingsFeatures": "Features",
|
"settingsFeatures": "Features",
|
||||||
"settingsNotifyWithHaptic": "Haptic when Notified",
|
"settingsNotifyWithHaptic": "Haptic when Notified",
|
||||||
"settingsNotifyWithHapticDescription": "Vibrate lightly when a new notification appears in the foreground.",
|
"settingsNotifyWithHapticDescription": "Vibrate lightly when a new notification appears in the foreground.",
|
||||||
|
"settingsExpandPostLink": "Expand Post Link",
|
||||||
|
"settingsExpandPostLinkDescription": "Expand the post link in the post list.",
|
||||||
|
"settingsExpandChatLink": "Expand Chat Link",
|
||||||
|
"settingsExpandChatLinkDescription": "Expand the chat link in the chat list.",
|
||||||
"settingsNetwork": "Network",
|
"settingsNetwork": "Network",
|
||||||
"settingsNetworkServer": "HyperNet Server",
|
"settingsNetworkServer": "HyperNet Server",
|
||||||
"settingsNetworkServerDescription": "Set the HyperNet server address, choose ours or build your own.",
|
"settingsNetworkServerDescription": "Set the HyperNet server address, choose ours or build your own.",
|
||||||
|
|||||||
@@ -194,6 +194,10 @@
|
|||||||
"settingsFeatures": "功能",
|
"settingsFeatures": "功能",
|
||||||
"settingsNotifyWithHaptic": "新通知时振动",
|
"settingsNotifyWithHaptic": "新通知时振动",
|
||||||
"settingsNotifyWithHapticDescription": "在应用在前台时收到新通知出现时出发轻量的振动。",
|
"settingsNotifyWithHapticDescription": "在应用在前台时收到新通知出现时出发轻量的振动。",
|
||||||
|
"settingsExpandPostLink": "展开帖子链接",
|
||||||
|
"settingsExpandPostLinkDescription": "在帖子列表中展开显示帖子中的链接。",
|
||||||
|
"settingsExpandChatLink": "展开聊天链接",
|
||||||
|
"settingsExpandChatLinkDescription": "在聊天信息中展开显示内容中的链接。",
|
||||||
"settingsNetwork": "网络",
|
"settingsNetwork": "网络",
|
||||||
"settingsNetworkServer": "HyperNet 服务器",
|
"settingsNetworkServer": "HyperNet 服务器",
|
||||||
"settingsNetworkServerDescription": "设置 HyperNet 服务器地址,选择我们提供的,或者自己搭建。",
|
"settingsNetworkServerDescription": "设置 HyperNet 服务器地址,选择我们提供的,或者自己搭建。",
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ class _AppSplashScreenState extends State<_AppSplashScreen> {
|
|||||||
try {
|
try {
|
||||||
final cfg = context.read<ConfigProvider>();
|
final cfg = context.read<ConfigProvider>();
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
cfg.calcDrawerSize(context);
|
cfg.calcDrawerSize(context, withMediaQuery: true);
|
||||||
});
|
});
|
||||||
final home = context.read<HomeWidgetProvider>();
|
final home = context.read<HomeWidgetProvider>();
|
||||||
await home.initialize();
|
await home.initialize();
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ const kAppBackgroundStoreKey = 'app_has_background';
|
|||||||
const kAppColorSchemeStoreKey = 'app_color_scheme';
|
const kAppColorSchemeStoreKey = 'app_color_scheme';
|
||||||
const kAppDrawerPreferCollapse = 'app_drawer_prefer_collapse';
|
const kAppDrawerPreferCollapse = 'app_drawer_prefer_collapse';
|
||||||
const kAppNotifyWithHaptic = 'app_notify_with_haptic';
|
const kAppNotifyWithHaptic = 'app_notify_with_haptic';
|
||||||
|
const kAppExpandPostLink = 'app_expand_post_link';
|
||||||
|
const kAppExpandChatLink = 'app_expand_chat_link';
|
||||||
|
|
||||||
const Map<String, FilterQuality> kImageQualityLevel = {
|
const Map<String, FilterQuality> kImageQualityLevel = {
|
||||||
'settingsImageQualityLowest': FilterQuality.none,
|
'settingsImageQualityLowest': FilterQuality.none,
|
||||||
@@ -39,14 +41,22 @@ class ConfigProvider extends ChangeNotifier {
|
|||||||
bool drawerIsCollapsed = false;
|
bool drawerIsCollapsed = false;
|
||||||
bool drawerIsExpanded = false;
|
bool drawerIsExpanded = false;
|
||||||
|
|
||||||
void calcDrawerSize(BuildContext context) {
|
void calcDrawerSize(BuildContext context, {bool withMediaQuery = false}) {
|
||||||
final rpb = ResponsiveBreakpoints.of(context);
|
bool newDrawerIsCollapsed = false;
|
||||||
final newDrawerIsCollapsed = rpb.smallerOrEqualTo(MOBILE);
|
bool newDrawerIsExpanded = false;
|
||||||
final newDrawerIsExpanded = rpb.largerThan(TABLET)
|
if (withMediaQuery) {
|
||||||
? (prefs.getBool(kAppDrawerPreferCollapse) ?? false)
|
newDrawerIsCollapsed = MediaQuery.of(context).size.width < 450;
|
||||||
? false
|
newDrawerIsExpanded = MediaQuery.of(context).size.width >= 451;
|
||||||
: true
|
} else {
|
||||||
: false;
|
final rpb = ResponsiveBreakpoints.of(context);
|
||||||
|
newDrawerIsCollapsed = rpb.smallerOrEqualTo(MOBILE);
|
||||||
|
newDrawerIsCollapsed = rpb.largerThan(TABLET)
|
||||||
|
? (prefs.getBool(kAppDrawerPreferCollapse) ?? false)
|
||||||
|
? false
|
||||||
|
: true
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
if (newDrawerIsExpanded != drawerIsExpanded || newDrawerIsCollapsed != drawerIsCollapsed) {
|
if (newDrawerIsExpanded != drawerIsExpanded || newDrawerIsCollapsed != drawerIsCollapsed) {
|
||||||
drawerIsExpanded = newDrawerIsExpanded;
|
drawerIsExpanded = newDrawerIsExpanded;
|
||||||
drawerIsCollapsed = newDrawerIsCollapsed;
|
drawerIsCollapsed = newDrawerIsCollapsed;
|
||||||
|
|||||||
428
lib/router.dart
428
lib/router.dart
@@ -34,246 +34,222 @@ import 'package:surface/widgets/about.dart';
|
|||||||
import 'package:surface/widgets/navigation/app_background.dart';
|
import 'package:surface/widgets/navigation/app_background.dart';
|
||||||
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
|
|
||||||
|
Widget _fadeThroughTransition(
|
||||||
|
BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
|
||||||
|
return FadeThroughTransition(
|
||||||
|
animation: animation,
|
||||||
|
secondaryAnimation: secondaryAnimation,
|
||||||
|
fillColor: Colors.transparent,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final _appRoutes = [
|
final _appRoutes = [
|
||||||
ShellRoute(
|
GoRoute(
|
||||||
builder: (context, state, child) => child,
|
path: '/',
|
||||||
|
name: 'home',
|
||||||
|
pageBuilder: (context, state) => CustomTransitionPage(
|
||||||
|
transitionsBuilder: _fadeThroughTransition,
|
||||||
|
child: const HomeScreen(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/posts',
|
||||||
|
name: 'explore',
|
||||||
|
pageBuilder: (context, state) => CustomTransitionPage(
|
||||||
|
transitionsBuilder: _fadeThroughTransition,
|
||||||
|
child: const ExploreScreen(),
|
||||||
|
),
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/write/:mode',
|
||||||
name: 'home',
|
name: 'postEditor',
|
||||||
pageBuilder: (context, state) => NoTransitionPage(
|
builder: (context, state) => PostEditorScreen(
|
||||||
child: const HomeScreen(),
|
mode: state.pathParameters['mode']!,
|
||||||
|
postEditId: int.tryParse(
|
||||||
|
state.uri.queryParameters['editing'] ?? '',
|
||||||
|
),
|
||||||
|
postReplyId: int.tryParse(
|
||||||
|
state.uri.queryParameters['replying'] ?? '',
|
||||||
|
),
|
||||||
|
postRepostId: int.tryParse(
|
||||||
|
state.uri.queryParameters['reposting'] ?? '',
|
||||||
|
),
|
||||||
|
extraProps: state.extra as PostEditorExtraProps?,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/posts',
|
path: '/search',
|
||||||
name: 'explore',
|
name: 'postSearch',
|
||||||
pageBuilder: (context, state) => NoTransitionPage(
|
builder: (context, state) => PostSearchScreen(
|
||||||
child: const ExploreScreen(),
|
initialTags: state.uri.queryParameters['tags']?.split(','),
|
||||||
),
|
initialCategories: state.uri.queryParameters['categories']?.split(','),
|
||||||
routes: [
|
|
||||||
GoRoute(
|
|
||||||
path: '/write/:mode',
|
|
||||||
name: 'postEditor',
|
|
||||||
builder: (context, state) => PostEditorScreen(
|
|
||||||
mode: state.pathParameters['mode']!,
|
|
||||||
postEditId: int.tryParse(
|
|
||||||
state.uri.queryParameters['editing'] ?? '',
|
|
||||||
),
|
|
||||||
postReplyId: int.tryParse(
|
|
||||||
state.uri.queryParameters['replying'] ?? '',
|
|
||||||
),
|
|
||||||
postRepostId: int.tryParse(
|
|
||||||
state.uri.queryParameters['reposting'] ?? '',
|
|
||||||
),
|
|
||||||
extraProps: state.extra as PostEditorExtraProps?,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/search',
|
|
||||||
name: 'postSearch',
|
|
||||||
builder: (context, state) => PostSearchScreen(
|
|
||||||
initialTags: state.uri.queryParameters['tags']?.split(','),
|
|
||||||
initialCategories: state.uri.queryParameters['categories']?.split(','),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/publishers/:name',
|
|
||||||
name: 'postPublisher',
|
|
||||||
builder: (context, state) => PostPublisherScreen(name: state.pathParameters['name']!),
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/:slug',
|
|
||||||
name: 'postDetail',
|
|
||||||
builder: (context, state) => PostDetailScreen(
|
|
||||||
slug: state.pathParameters['slug']!,
|
|
||||||
preload: state.extra as SnPost?,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/account',
|
|
||||||
name: 'account',
|
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
|
||||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
|
||||||
return FadeThroughTransition(
|
|
||||||
animation: animation,
|
|
||||||
secondaryAnimation: secondaryAnimation,
|
|
||||||
fillColor: Colors.transparent,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: const AccountScreen(),
|
|
||||||
),
|
|
||||||
routes: [],
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/chat',
|
|
||||||
name: 'chat',
|
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
|
||||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
|
||||||
return FadeThroughTransition(
|
|
||||||
animation: animation,
|
|
||||||
secondaryAnimation: secondaryAnimation,
|
|
||||||
fillColor: Colors.transparent,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: const ChatScreen(),
|
|
||||||
),
|
|
||||||
routes: [
|
|
||||||
GoRoute(
|
|
||||||
path: '/:scope/:alias',
|
|
||||||
name: 'chatRoom',
|
|
||||||
builder: (context, state) => AppBackground(
|
|
||||||
child: ChatRoomScreen(
|
|
||||||
scope: state.pathParameters['scope']!,
|
|
||||||
alias: state.pathParameters['alias']!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/:scope/:alias/call',
|
|
||||||
name: 'chatCallRoom',
|
|
||||||
builder: (context, state) => AppBackground(
|
|
||||||
child: CallRoomScreen(
|
|
||||||
scope: state.pathParameters['scope']!,
|
|
||||||
alias: state.pathParameters['alias']!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/:scope/:alias/detail',
|
|
||||||
name: 'channelDetail',
|
|
||||||
builder: (context, state) => AppBackground(
|
|
||||||
child: ChannelDetailScreen(
|
|
||||||
scope: state.pathParameters['scope']!,
|
|
||||||
alias: state.pathParameters['alias']!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/manage',
|
|
||||||
name: 'chatManage',
|
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
|
||||||
child: ChatManageScreen(
|
|
||||||
editingChannelAlias: state.uri.queryParameters['editing'],
|
|
||||||
),
|
|
||||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
|
||||||
return FadeThroughTransition(
|
|
||||||
animation: animation,
|
|
||||||
secondaryAnimation: secondaryAnimation,
|
|
||||||
fillColor: Colors.transparent,
|
|
||||||
child: AppBackground(
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/:alias',
|
|
||||||
name: 'realmDetail',
|
|
||||||
builder: (context, state) => AppBackground(
|
|
||||||
child: RealmDetailScreen(alias: state.pathParameters['alias']!),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/realm',
|
|
||||||
name: 'realm',
|
|
||||||
pageBuilder: (context, state) => NoTransitionPage(
|
|
||||||
child: const RealmScreen(),
|
|
||||||
),
|
|
||||||
routes: [
|
|
||||||
GoRoute(
|
|
||||||
path: '/manage',
|
|
||||||
name: 'realmManage',
|
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
|
||||||
child: RealmManageScreen(
|
|
||||||
editingRealmAlias: state.uri.queryParameters['editing'],
|
|
||||||
),
|
|
||||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
|
||||||
return FadeThroughTransition(
|
|
||||||
animation: animation,
|
|
||||||
secondaryAnimation: secondaryAnimation,
|
|
||||||
fillColor: Colors.transparent,
|
|
||||||
child: AppBackground(
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/album',
|
|
||||||
name: 'album',
|
|
||||||
pageBuilder: (context, state) => NoTransitionPage(
|
|
||||||
child: const AlbumScreen(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/friend',
|
path: '/publishers/:name',
|
||||||
name: 'friend',
|
name: 'postPublisher',
|
||||||
pageBuilder: (context, state) => NoTransitionPage(
|
builder: (context, state) => PostPublisherScreen(name: state.pathParameters['name']!),
|
||||||
child: const FriendScreen(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/notification',
|
path: '/:slug',
|
||||||
name: 'notification',
|
name: 'postDetail',
|
||||||
pageBuilder: (context, state) => NoTransitionPage(
|
builder: (context, state) => PostDetailScreen(
|
||||||
child: const NotificationScreen(),
|
slug: state.pathParameters['slug']!,
|
||||||
|
preload: state.extra as SnPost?,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
ShellRoute(
|
GoRoute(
|
||||||
builder: (context, state, child) => child,
|
path: '/account',
|
||||||
|
name: 'account',
|
||||||
|
pageBuilder: (context, state) => CustomTransitionPage(
|
||||||
|
transitionsBuilder: _fadeThroughTransition,
|
||||||
|
child: const AccountScreen(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/chat',
|
||||||
|
name: 'chat',
|
||||||
|
pageBuilder: (context, state) => CustomTransitionPage(
|
||||||
|
transitionsBuilder: _fadeThroughTransition,
|
||||||
|
child: const ChatScreen(),
|
||||||
|
),
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/auth/login',
|
path: '/:scope/:alias',
|
||||||
name: 'authLogin',
|
name: 'chatRoom',
|
||||||
builder: (context, state) => LoginScreen(),
|
builder: (context, state) => AppBackground(
|
||||||
|
child: ChatRoomScreen(
|
||||||
|
scope: state.pathParameters['scope']!,
|
||||||
|
alias: state.pathParameters['alias']!,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/auth/register',
|
path: '/:scope/:alias/call',
|
||||||
name: 'authRegister',
|
name: 'chatCallRoom',
|
||||||
builder: (context, state) => RegisterScreen(),
|
builder: (context, state) => AppBackground(
|
||||||
|
child: CallRoomScreen(
|
||||||
|
scope: state.pathParameters['scope']!,
|
||||||
|
alias: state.pathParameters['alias']!,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/reports',
|
path: '/:scope/:alias/detail',
|
||||||
name: 'abuseReport',
|
name: 'channelDetail',
|
||||||
builder: (context, state) => AbuseReportScreen(),
|
builder: (context, state) => AppBackground(
|
||||||
|
child: ChannelDetailScreen(
|
||||||
|
scope: state.pathParameters['scope']!,
|
||||||
|
alias: state.pathParameters['alias']!,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/account/profile/edit',
|
path: '/manage',
|
||||||
name: 'accountProfileEdit',
|
name: 'chatManage',
|
||||||
builder: (context, state) => ProfileEditScreen(),
|
pageBuilder: (context, state) => CustomTransitionPage(
|
||||||
),
|
child: ChatManageScreen(
|
||||||
GoRoute(
|
editingChannelAlias: state.uri.queryParameters['editing'],
|
||||||
path: '/account/publishers',
|
),
|
||||||
name: 'accountPublishers',
|
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
||||||
builder: (context, state) => PublisherScreen(),
|
return FadeThroughTransition(
|
||||||
),
|
animation: animation,
|
||||||
GoRoute(
|
secondaryAnimation: secondaryAnimation,
|
||||||
path: '/account/publishers/new',
|
fillColor: Colors.transparent,
|
||||||
name: 'accountPublisherNew',
|
child: child,
|
||||||
builder: (context, state) => AccountPublisherNewScreen(),
|
);
|
||||||
),
|
},
|
||||||
GoRoute(
|
|
||||||
path: '/account/publishers/edit/:name',
|
|
||||||
name: 'accountPublisherEdit',
|
|
||||||
builder: (context, state) => AccountPublisherEditScreen(
|
|
||||||
name: state.pathParameters['name']!,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/realm',
|
||||||
|
name: 'realm',
|
||||||
|
pageBuilder: (context, state) => CustomTransitionPage(
|
||||||
|
transitionsBuilder: _fadeThroughTransition,
|
||||||
|
child: const RealmScreen(),
|
||||||
|
),
|
||||||
|
routes: [
|
||||||
|
GoRoute(
|
||||||
|
path: '/:alias',
|
||||||
|
name: 'realmDetail',
|
||||||
|
builder: (context, state) => RealmDetailScreen(alias: state.pathParameters['alias']!),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/manage',
|
||||||
|
name: 'realmManage',
|
||||||
|
pageBuilder: (context, state) => CustomTransitionPage(
|
||||||
|
transitionsBuilder: _fadeThroughTransition,
|
||||||
|
child: RealmManageScreen(
|
||||||
|
editingRealmAlias: state.uri.queryParameters['editing'],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/album',
|
||||||
|
name: 'album',
|
||||||
|
pageBuilder: (context, state) => CustomTransitionPage(
|
||||||
|
transitionsBuilder: _fadeThroughTransition,
|
||||||
|
child: const AlbumScreen(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/friend',
|
||||||
|
name: 'friend',
|
||||||
|
pageBuilder: (context, state) => NoTransitionPage(
|
||||||
|
child: const FriendScreen(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/notification',
|
||||||
|
name: 'notification',
|
||||||
|
pageBuilder: (context, state) => NoTransitionPage(
|
||||||
|
child: const NotificationScreen(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/auth/login',
|
||||||
|
name: 'authLogin',
|
||||||
|
builder: (context, state) => LoginScreen(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/auth/register',
|
||||||
|
name: 'authRegister',
|
||||||
|
builder: (context, state) => RegisterScreen(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/reports',
|
||||||
|
name: 'abuseReport',
|
||||||
|
builder: (context, state) => AbuseReportScreen(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/account/profile/edit',
|
||||||
|
name: 'accountProfileEdit',
|
||||||
|
builder: (context, state) => ProfileEditScreen(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/account/publishers',
|
||||||
|
name: 'accountPublishers',
|
||||||
|
builder: (context, state) => PublisherScreen(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/account/publishers/new',
|
||||||
|
name: 'accountPublisherNew',
|
||||||
|
builder: (context, state) => AccountPublisherNewScreen(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/account/publishers/edit/:name',
|
||||||
|
name: 'accountPublisherEdit',
|
||||||
|
builder: (context, state) => AccountPublisherEditScreen(
|
||||||
|
name: state.pathParameters['name']!,
|
||||||
|
),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/account/:name',
|
path: '/account/:name',
|
||||||
name: 'accountProfilePage',
|
name: 'accountProfilePage',
|
||||||
@@ -281,25 +257,15 @@ final _appRoutes = [
|
|||||||
child: UserScreen(name: state.pathParameters['name']!),
|
child: UserScreen(name: state.pathParameters['name']!),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ShellRoute(
|
GoRoute(
|
||||||
builder: (context, state, child) => child,
|
path: '/settings',
|
||||||
routes: [
|
name: 'settings',
|
||||||
GoRoute(
|
builder: (context, state) => SettingsScreen(),
|
||||||
path: '/settings',
|
|
||||||
name: 'settings',
|
|
||||||
builder: (context, state) => SettingsScreen(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
ShellRoute(
|
GoRoute(
|
||||||
builder: (context, state, child) => child,
|
path: '/about',
|
||||||
routes: [
|
name: 'about',
|
||||||
GoRoute(
|
builder: (context, state) => AboutScreen(),
|
||||||
path: '/about',
|
|
||||||
name: 'about',
|
|
||||||
builder: (context, state) => AboutScreen(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import 'package:surface/types/check_in.dart';
|
|||||||
import 'package:surface/types/post.dart';
|
import 'package:surface/types/post.dart';
|
||||||
import 'package:surface/widgets/account/account_image.dart';
|
import 'package:surface/widgets/account/account_image.dart';
|
||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
|
||||||
import 'package:surface/widgets/universal_image.dart';
|
import 'package:surface/widgets/universal_image.dart';
|
||||||
|
|
||||||
const Map<String, (String, IconData, Color)> kBadgesMeta = {
|
const Map<String, (String, IconData, Color)> kBadgesMeta = {
|
||||||
@@ -596,7 +595,7 @@ class _UserScreenState extends State<UserScreen> with SingleTickerProviderStateM
|
|||||||
subtitle: Text('@${ele.name}'),
|
subtitle: Text('@${ele.name}'),
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
GoRouter.of(context).pushNamed(
|
GoRouter.of(context).goNamed(
|
||||||
'postPublisher',
|
'postPublisher',
|
||||||
pathParameters: {'name': ele.name},
|
pathParameters: {'name': ele.name},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -276,6 +276,30 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
CheckboxListTile(
|
||||||
|
secondary: const Icon(Symbols.link),
|
||||||
|
title: Text('settingsExpandPostLink').tr(),
|
||||||
|
subtitle: Text('settingsExpandPostLinkDescription').tr(),
|
||||||
|
contentPadding: const EdgeInsets.only(left: 24, right: 17),
|
||||||
|
value: _prefs.getBool(kAppExpandPostLink) ?? true,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_prefs.setBool(kAppExpandPostLink, value ?? false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
CheckboxListTile(
|
||||||
|
secondary: const Icon(Symbols.chat),
|
||||||
|
title: Text('settingsExpandChatLink').tr(),
|
||||||
|
subtitle: Text('settingsExpandChatLinkDescription').tr(),
|
||||||
|
contentPadding: const EdgeInsets.only(left: 24, right: 17),
|
||||||
|
value: _prefs.getBool(kAppExpandChatLink) ?? true,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_prefs.setBool(kAppExpandChatLink, value ?? false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Column(
|
Column(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
|||||||
import 'package:popover/popover.dart';
|
import 'package:popover/popover.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
import 'package:surface/providers/config.dart';
|
||||||
import 'package:surface/providers/user_directory.dart';
|
import 'package:surface/providers/user_directory.dart';
|
||||||
import 'package:surface/providers/userinfo.dart';
|
import 'package:surface/providers/userinfo.dart';
|
||||||
import 'package:surface/types/chat.dart';
|
import 'package:surface/types/chat.dart';
|
||||||
@@ -53,6 +54,8 @@ class ChatMessage extends StatelessWidget {
|
|||||||
|
|
||||||
final dateFormatter = DateFormat('MM/dd HH:mm');
|
final dateFormatter = DateFormat('MM/dd HH:mm');
|
||||||
|
|
||||||
|
final cfg = context.read<ConfigProvider>();
|
||||||
|
|
||||||
return SwipeTo(
|
return SwipeTo(
|
||||||
key: Key('chat-message-${data.id}'),
|
key: Key('chat-message-${data.id}'),
|
||||||
iconOnLeftSwipe: Symbols.reply,
|
iconOnLeftSwipe: Symbols.reply,
|
||||||
@@ -192,7 +195,10 @@ class ChatMessage extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
).opacity(isPending ? 0.5 : 1),
|
).opacity(isPending ? 0.5 : 1),
|
||||||
),
|
),
|
||||||
if (data.body['text'] != null && data.type == 'messages.new' && (data.body['text']?.isNotEmpty ?? false))
|
if (data.body['text'] != null &&
|
||||||
|
data.type == 'messages.new' &&
|
||||||
|
(data.body['text']?.isNotEmpty ?? false) &&
|
||||||
|
(cfg.prefs.getBool(kAppExpandChatLink) ?? true))
|
||||||
LinkPreviewWidget(text: data.body['text']!),
|
LinkPreviewWidget(text: data.body['text']!),
|
||||||
if (data.preload?.attachments?.isNotEmpty ?? false)
|
if (data.preload?.attachments?.isNotEmpty ?? false)
|
||||||
AttachmentList(
|
AttachmentList(
|
||||||
|
|||||||
@@ -7,12 +7,11 @@ import 'package:marquee/marquee.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:responsive_framework/responsive_framework.dart';
|
import 'package:responsive_framework/responsive_framework.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
import 'package:surface/providers/link_preview.dart';
|
||||||
import 'package:surface/types/link.dart';
|
import 'package:surface/types/link.dart';
|
||||||
import 'package:surface/widgets/universal_image.dart';
|
import 'package:surface/widgets/universal_image.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
import '../providers/link_preview.dart';
|
|
||||||
|
|
||||||
class LinkPreviewWidget extends StatefulWidget {
|
class LinkPreviewWidget extends StatefulWidget {
|
||||||
final String text;
|
final String text;
|
||||||
|
|
||||||
@@ -81,8 +80,9 @@ class _LinkPreviewEntry extends StatelessWidget {
|
|||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
child: AutoResizeUniversalImage(
|
child: AutoResizeUniversalImage(
|
||||||
meta.image!,
|
meta.image!.startsWith('//') ? 'https:${meta.image}' : meta.image!,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -12,7 +11,6 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
import 'package:surface/providers/config.dart';
|
import 'package:surface/providers/config.dart';
|
||||||
import 'package:surface/providers/navigation.dart';
|
import 'package:surface/providers/navigation.dart';
|
||||||
import 'package:surface/widgets/connection_indicator.dart';
|
import 'package:surface/widgets/connection_indicator.dart';
|
||||||
import 'package:surface/widgets/dialog.dart';
|
|
||||||
import 'package:surface/widgets/navigation/app_background.dart';
|
import 'package:surface/widgets/navigation/app_background.dart';
|
||||||
import 'package:surface/widgets/navigation/app_bottom_navigation.dart';
|
import 'package:surface/widgets/navigation/app_bottom_navigation.dart';
|
||||||
import 'package:surface/widgets/navigation/app_drawer_navigation.dart';
|
import 'package:surface/widgets/navigation/app_drawer_navigation.dart';
|
||||||
|
|||||||
@@ -203,6 +203,8 @@ class PostItem extends StatelessWidget {
|
|||||||
?.where((ele) => ele?.mediaType != SnMediaType.image || data.type != 'article')
|
?.where((ele) => ele?.mediaType != SnMediaType.image || data.type != 'article')
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
final cfg = context.read<ConfigProvider>();
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
@@ -261,7 +263,7 @@ class PostItem extends StatelessWidget {
|
|||||||
fit: showFullPost ? BoxFit.cover : BoxFit.contain,
|
fit: showFullPost ? BoxFit.cover : BoxFit.contain,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
),
|
),
|
||||||
if (data.body['content'] != null)
|
if (data.body['content'] != null && (cfg.prefs.getBool(kAppExpandPostLink) ?? true))
|
||||||
LinkPreviewWidget(
|
LinkPreviewWidget(
|
||||||
text: data.body['content'],
|
text: data.body['content'],
|
||||||
).padding(horizontal: 4),
|
).padding(horizontal: 4),
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 2.2.2+55
|
version: 2.2.2+56
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.5.4
|
sdk: ^3.5.4
|
||||||
|
|||||||
Reference in New Issue
Block a user