feat: add startup bulletin; switch to edit mode when click text on md preview.
This commit is contained in:
@@ -5,4 +5,5 @@ class SPKeys {
|
||||
static final String accessToken = 'USER_ACCESS_TOKEN';
|
||||
static final String loginEmail = 'USER_LOGIN_EMAIL';
|
||||
static final String ignoredUpdateVersion = 'IGNORED_UPDATE_VERSION';
|
||||
static final String readBulletinId = 'READ_BULLETIN_ID';
|
||||
}
|
||||
|
||||
+39
-13
@@ -63,6 +63,8 @@ class Api {
|
||||
return res;
|
||||
};
|
||||
|
||||
static final _fullPathRegExp = RegExp('http(s?)://');
|
||||
|
||||
static Future<T?> _get<T>(
|
||||
String path,
|
||||
BeanBuilder<T> builder, {
|
||||
@@ -72,13 +74,15 @@ class Api {
|
||||
}) =>
|
||||
http
|
||||
.get(
|
||||
Uri(
|
||||
scheme: Apis.apiScheme,
|
||||
host: Apis.apiHost,
|
||||
port: Apis.apiPort,
|
||||
queryParameters: queryParams,
|
||||
path: path,
|
||||
),
|
||||
path.startsWith(_fullPathRegExp)
|
||||
? Uri.parse(path)
|
||||
: Uri(
|
||||
scheme: Apis.apiScheme,
|
||||
host: Apis.apiHost,
|
||||
port: Apis.apiPort,
|
||||
queryParameters: queryParams,
|
||||
path: path,
|
||||
),
|
||||
headers: <String, String>{
|
||||
HttpHeaders.contentTypeHeader: ContentType.json.toString(),
|
||||
}..addAll(
|
||||
@@ -103,12 +107,14 @@ class Api {
|
||||
}) =>
|
||||
http
|
||||
.post(
|
||||
Uri(
|
||||
scheme: Apis.apiScheme,
|
||||
host: Apis.apiHost,
|
||||
port: Apis.apiPort,
|
||||
path: path,
|
||||
),
|
||||
path.startsWith(_fullPathRegExp)
|
||||
? Uri.parse(path)
|
||||
: Uri(
|
||||
scheme: Apis.apiScheme,
|
||||
host: Apis.apiHost,
|
||||
port: Apis.apiPort,
|
||||
path: path,
|
||||
),
|
||||
body: jsonEncode(body),
|
||||
headers: <String, String>{
|
||||
HttpHeaders.contentTypeHeader: ContentType.json.toString(),
|
||||
@@ -199,6 +205,26 @@ class Api {
|
||||
Apis.scheme.userLikes,
|
||||
(e) => (e['list'] as List).cast<int>(),
|
||||
);
|
||||
|
||||
static Future<AppBulletinResp?> checkBulletin(bool isWeb) => _get(
|
||||
Apis.appBulletinUrl(isWeb),
|
||||
AppBulletinResp.fromMap,
|
||||
ignoreErrorHandle: true,
|
||||
ignoreToken: true,
|
||||
).catchError((_) {});
|
||||
}
|
||||
|
||||
class AppBulletinResp {
|
||||
int? id;
|
||||
bool? once;
|
||||
String? title;
|
||||
String? content;
|
||||
|
||||
AppBulletinResp.fromMap(Map map)
|
||||
: id = map['id'],
|
||||
once = map['once'],
|
||||
title = map['title'],
|
||||
content = map['content'];
|
||||
}
|
||||
|
||||
class MarketSchemeTransMetaDataResp {
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:dde_gesture_manager/themes/dark.dart';
|
||||
import 'package:dde_gesture_manager/themes/light.dart';
|
||||
import 'package:dde_gesture_manager/utils/helper.dart';
|
||||
import 'package:dde_gesture_manager/utils/init.dart';
|
||||
import 'package:dde_gesture_manager/utils/notificator.dart';
|
||||
import 'package:dde_gesture_manager/utils/simple_throttle.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -89,6 +90,7 @@ class MyApp extends StatelessWidget {
|
||||
Sentry.captureMessage,
|
||||
timeout: const Duration(days: 1),
|
||||
)?.call('App launched');
|
||||
SimpleThrottle.throttledFunc(_checkBulletin, timeout: const Duration(days: 1))?.call(context);
|
||||
});
|
||||
return Container();
|
||||
}),
|
||||
@@ -112,3 +114,14 @@ void _checkAuthStatus(BuildContext context) {
|
||||
H().lastCheckAuthStatusTime = DateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
void _checkBulletin(BuildContext context) {
|
||||
Api.checkBulletin(kIsWeb).then((value) {
|
||||
if (value != null && value.id != null) {
|
||||
if (value.once == false || (H().sp.getInt(SPKeys.readBulletinId) ?? 0) < value.id!) {
|
||||
Notificator.showAlert(title: value.title ?? '', description: value.content ?? '');
|
||||
}
|
||||
H().sp.setInt(SPKeys.readBulletinId, value.id!);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -46,6 +46,14 @@ class _DMarkdownFieldState extends State<DMarkdownField> {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
VoidCallback? get _onMdPreviewTap => widget.readOnly
|
||||
? null
|
||||
: () {
|
||||
setState(() {
|
||||
_previewText = null;
|
||||
});
|
||||
};
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Focus(
|
||||
@@ -62,19 +70,14 @@ class _DMarkdownFieldState extends State<DMarkdownField> {
|
||||
),
|
||||
child: isPreview
|
||||
? GestureDetector(
|
||||
onTap: widget.readOnly
|
||||
? null
|
||||
: () {
|
||||
setState(() {
|
||||
_previewText = null;
|
||||
});
|
||||
},
|
||||
onTap: _onMdPreviewTap,
|
||||
child: MouseRegion(
|
||||
cursor: widget.readOnly ? SystemMouseCursors.basic : SystemMouseCursors.text,
|
||||
child: MdPreview(
|
||||
text: _previewText ?? '',
|
||||
padding: EdgeInsets.only(left: 15),
|
||||
onTapLink: H.launchURL,
|
||||
richTap: _onMdPreviewTap,
|
||||
textStyle: context.t.textTheme.bodyText2,
|
||||
onCodeCopied: () {
|
||||
Notificator.success(
|
||||
|
||||
Reference in New Issue
Block a user