mirror of
https://github.com/haorendashu/nowser.git
synced 2025-12-17 01:44:19 +01:00
add web apps
This commit is contained in:
@@ -196,6 +196,15 @@ class _WebHomeComponent extends State<WebHomeComponent> {
|
|||||||
main = WebHomeBtnComponent(bookmark!);
|
main = WebHomeBtnComponent(bookmark!);
|
||||||
} else {
|
} else {
|
||||||
if (bookmarks.length == index) {
|
if (bookmarks.length == index) {
|
||||||
|
main = GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
RouterUtil.router(context, RouterPath.WEB_APPS);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
child: Icon(Icons.apps),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (bookmarks.length + 1 == index) {
|
||||||
main = GestureDetector(
|
main = GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
BookmarkEditDialog.show(
|
BookmarkEditDialog.show(
|
||||||
|
|||||||
@@ -13,4 +13,6 @@ class Base {
|
|||||||
|
|
||||||
static String USER_AGENT =
|
static String USER_AGENT =
|
||||||
"${Base.APP_NAME} ${PlatformUtil.getPlatformName()} ${Base.VERSION_NAME}";
|
"${Base.APP_NAME} ${PlatformUtil.getPlatformName()} ${Base.VERSION_NAME}";
|
||||||
|
|
||||||
|
static String WEB_APPS = "https://nowser.nostrmo.com/jsons/webapps.json";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ class RouterPath {
|
|||||||
static const String ME = "/me";
|
static const String ME = "/me";
|
||||||
static const String KEYS = "/keys";
|
static const String KEYS = "/keys";
|
||||||
static const String APPS = "/apps";
|
static const String APPS = "/apps";
|
||||||
|
static const String WEB_APPS = "/webApps";
|
||||||
static const String ADD_REMOTE_APP = "/addRemoteApp";
|
static const String ADD_REMOTE_APP = "/addRemoteApp";
|
||||||
static const String APP_DETAIL = "/appDetail";
|
static const String APP_DETAIL = "/appDetail";
|
||||||
static const String HISTORY = "/history";
|
static const String HISTORY = "/history";
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Add_to_index": MessageLookupByLibrary.simpleMessage("Add to index"),
|
"Add_to_index": MessageLookupByLibrary.simpleMessage("Add to index"),
|
||||||
"Add_to_quick_action":
|
"Add_to_quick_action":
|
||||||
MessageLookupByLibrary.simpleMessage("Add to quick action"),
|
MessageLookupByLibrary.simpleMessage("Add to quick action"),
|
||||||
|
"All": MessageLookupByLibrary.simpleMessage("All"),
|
||||||
"Allow": MessageLookupByLibrary.simpleMessage("Allow"),
|
"Allow": MessageLookupByLibrary.simpleMessage("Allow"),
|
||||||
"Alway_reject": MessageLookupByLibrary.simpleMessage("Alway reject"),
|
"Alway_reject": MessageLookupByLibrary.simpleMessage("Alway reject"),
|
||||||
"Always": MessageLookupByLibrary.simpleMessage("Always"),
|
"Always": MessageLookupByLibrary.simpleMessage("Always"),
|
||||||
@@ -89,6 +90,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Get_Public_Key":
|
"Get_Public_Key":
|
||||||
MessageLookupByLibrary.simpleMessage("Get Public Key"),
|
MessageLookupByLibrary.simpleMessage("Get Public Key"),
|
||||||
"Get_Relays": MessageLookupByLibrary.simpleMessage("Get Relays"),
|
"Get_Relays": MessageLookupByLibrary.simpleMessage("Get Relays"),
|
||||||
|
"Group_Chat": MessageLookupByLibrary.simpleMessage("Group Chat"),
|
||||||
"Historys": MessageLookupByLibrary.simpleMessage("Historys"),
|
"Historys": MessageLookupByLibrary.simpleMessage("Historys"),
|
||||||
"Incognito": MessageLookupByLibrary.simpleMessage("Incognito"),
|
"Incognito": MessageLookupByLibrary.simpleMessage("Incognito"),
|
||||||
"Input_can_not_be_null":
|
"Input_can_not_be_null":
|
||||||
@@ -103,7 +105,10 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Login_fail": MessageLookupByLibrary.simpleMessage("Login_fail"),
|
"Login_fail": MessageLookupByLibrary.simpleMessage("Login_fail"),
|
||||||
"Login_with_Nesigner":
|
"Login_with_Nesigner":
|
||||||
MessageLookupByLibrary.simpleMessage("Login with Nesigner"),
|
MessageLookupByLibrary.simpleMessage("Login with Nesigner"),
|
||||||
|
"Long_Form": MessageLookupByLibrary.simpleMessage("Long Form"),
|
||||||
|
"Marketplaces": MessageLookupByLibrary.simpleMessage("Marketplaces"),
|
||||||
"Name": MessageLookupByLibrary.simpleMessage("Name"),
|
"Name": MessageLookupByLibrary.simpleMessage("Name"),
|
||||||
|
"Notes": MessageLookupByLibrary.simpleMessage("Notes"),
|
||||||
"Open_backgroundly":
|
"Open_backgroundly":
|
||||||
MessageLookupByLibrary.simpleMessage("Open backgroundly"),
|
MessageLookupByLibrary.simpleMessage("Open backgroundly"),
|
||||||
"Open_image_in_a_New_Tab":
|
"Open_image_in_a_New_Tab":
|
||||||
@@ -114,6 +119,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
MessageLookupByLibrary.simpleMessage("Open with Incognito Mode"),
|
MessageLookupByLibrary.simpleMessage("Open with Incognito Mode"),
|
||||||
"Pendding_connect_remote_apps": MessageLookupByLibrary.simpleMessage(
|
"Pendding_connect_remote_apps": MessageLookupByLibrary.simpleMessage(
|
||||||
"Pendding connect remote apps"),
|
"Pendding connect remote apps"),
|
||||||
|
"Photos": MessageLookupByLibrary.simpleMessage("Photos"),
|
||||||
"Privacy": MessageLookupByLibrary.simpleMessage("Privacy"),
|
"Privacy": MessageLookupByLibrary.simpleMessage("Privacy"),
|
||||||
"Pubkey": MessageLookupByLibrary.simpleMessage("Pubkey"),
|
"Pubkey": MessageLookupByLibrary.simpleMessage("Pubkey"),
|
||||||
"Reasonable": MessageLookupByLibrary.simpleMessage("Reasonable"),
|
"Reasonable": MessageLookupByLibrary.simpleMessage("Reasonable"),
|
||||||
@@ -134,9 +140,13 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
MessageLookupByLibrary.simpleMessage("Show more logs"),
|
MessageLookupByLibrary.simpleMessage("Show more logs"),
|
||||||
"Sign_Event": MessageLookupByLibrary.simpleMessage("Sign Event"),
|
"Sign_Event": MessageLookupByLibrary.simpleMessage("Sign Event"),
|
||||||
"Stars": MessageLookupByLibrary.simpleMessage("Stars"),
|
"Stars": MessageLookupByLibrary.simpleMessage("Stars"),
|
||||||
|
"Streaming": MessageLookupByLibrary.simpleMessage("Streaming"),
|
||||||
"ThemeStyle": MessageLookupByLibrary.simpleMessage("ThemeStyle"),
|
"ThemeStyle": MessageLookupByLibrary.simpleMessage("ThemeStyle"),
|
||||||
|
"Tools": MessageLookupByLibrary.simpleMessage("Tools"),
|
||||||
"Url": MessageLookupByLibrary.simpleMessage("Url"),
|
"Url": MessageLookupByLibrary.simpleMessage("Url"),
|
||||||
"WEB": MessageLookupByLibrary.simpleMessage("WEB"),
|
"WEB": MessageLookupByLibrary.simpleMessage("WEB"),
|
||||||
|
"Web_APPs": MessageLookupByLibrary.simpleMessage("Web APPs"),
|
||||||
|
"Zaps": MessageLookupByLibrary.simpleMessage("Zaps"),
|
||||||
"a": MessageLookupByLibrary.simpleMessage("a"),
|
"a": MessageLookupByLibrary.simpleMessage("a"),
|
||||||
"auto": MessageLookupByLibrary.simpleMessage("auto"),
|
"auto": MessageLookupByLibrary.simpleMessage("auto"),
|
||||||
"detail": MessageLookupByLibrary.simpleMessage("detail"),
|
"detail": MessageLookupByLibrary.simpleMessage("detail"),
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Add_bookmark": MessageLookupByLibrary.simpleMessage("添加书签"),
|
"Add_bookmark": MessageLookupByLibrary.simpleMessage("添加书签"),
|
||||||
"Add_to_index": MessageLookupByLibrary.simpleMessage("添加到首页"),
|
"Add_to_index": MessageLookupByLibrary.simpleMessage("添加到首页"),
|
||||||
"Add_to_quick_action": MessageLookupByLibrary.simpleMessage("添加到快捷方式"),
|
"Add_to_quick_action": MessageLookupByLibrary.simpleMessage("添加到快捷方式"),
|
||||||
|
"All": MessageLookupByLibrary.simpleMessage("全部"),
|
||||||
"Allow": MessageLookupByLibrary.simpleMessage("允许"),
|
"Allow": MessageLookupByLibrary.simpleMessage("允许"),
|
||||||
"Alway_reject": MessageLookupByLibrary.simpleMessage("总是拒绝"),
|
"Alway_reject": MessageLookupByLibrary.simpleMessage("总是拒绝"),
|
||||||
"Always": MessageLookupByLibrary.simpleMessage("总是"),
|
"Always": MessageLookupByLibrary.simpleMessage("总是"),
|
||||||
@@ -77,6 +78,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
MessageLookupByLibrary.simpleMessage("生成一个秘钥"),
|
MessageLookupByLibrary.simpleMessage("生成一个秘钥"),
|
||||||
"Get_Public_Key": MessageLookupByLibrary.simpleMessage("获取公钥"),
|
"Get_Public_Key": MessageLookupByLibrary.simpleMessage("获取公钥"),
|
||||||
"Get_Relays": MessageLookupByLibrary.simpleMessage("获取中继"),
|
"Get_Relays": MessageLookupByLibrary.simpleMessage("获取中继"),
|
||||||
|
"Group_Chat": MessageLookupByLibrary.simpleMessage("群组聊天"),
|
||||||
"Historys": MessageLookupByLibrary.simpleMessage("历史"),
|
"Historys": MessageLookupByLibrary.simpleMessage("历史"),
|
||||||
"Incognito": MessageLookupByLibrary.simpleMessage("无痕"),
|
"Incognito": MessageLookupByLibrary.simpleMessage("无痕"),
|
||||||
"Input_can_not_be_null": MessageLookupByLibrary.simpleMessage("输入不能为空"),
|
"Input_can_not_be_null": MessageLookupByLibrary.simpleMessage("输入不能为空"),
|
||||||
@@ -89,7 +91,10 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Login_fail": MessageLookupByLibrary.simpleMessage("登录失败"),
|
"Login_fail": MessageLookupByLibrary.simpleMessage("登录失败"),
|
||||||
"Login_with_Nesigner":
|
"Login_with_Nesigner":
|
||||||
MessageLookupByLibrary.simpleMessage("使用 Nesigner 登录"),
|
MessageLookupByLibrary.simpleMessage("使用 Nesigner 登录"),
|
||||||
|
"Long_Form": MessageLookupByLibrary.simpleMessage("长文本"),
|
||||||
|
"Marketplaces": MessageLookupByLibrary.simpleMessage("市场"),
|
||||||
"Name": MessageLookupByLibrary.simpleMessage("名称"),
|
"Name": MessageLookupByLibrary.simpleMessage("名称"),
|
||||||
|
"Notes": MessageLookupByLibrary.simpleMessage("笔记"),
|
||||||
"Open_backgroundly": MessageLookupByLibrary.simpleMessage("后台打开"),
|
"Open_backgroundly": MessageLookupByLibrary.simpleMessage("后台打开"),
|
||||||
"Open_image_in_a_New_Tab":
|
"Open_image_in_a_New_Tab":
|
||||||
MessageLookupByLibrary.simpleMessage("新标签打开图片"),
|
MessageLookupByLibrary.simpleMessage("新标签打开图片"),
|
||||||
@@ -98,6 +103,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
MessageLookupByLibrary.simpleMessage("无痕模式打开"),
|
MessageLookupByLibrary.simpleMessage("无痕模式打开"),
|
||||||
"Pendding_connect_remote_apps":
|
"Pendding_connect_remote_apps":
|
||||||
MessageLookupByLibrary.simpleMessage("待链接的远程应用"),
|
MessageLookupByLibrary.simpleMessage("待链接的远程应用"),
|
||||||
|
"Photos": MessageLookupByLibrary.simpleMessage("照片"),
|
||||||
"Privacy": MessageLookupByLibrary.simpleMessage("隐私"),
|
"Privacy": MessageLookupByLibrary.simpleMessage("隐私"),
|
||||||
"Pubkey": MessageLookupByLibrary.simpleMessage("公钥"),
|
"Pubkey": MessageLookupByLibrary.simpleMessage("公钥"),
|
||||||
"Reasonable": MessageLookupByLibrary.simpleMessage("合理的授权"),
|
"Reasonable": MessageLookupByLibrary.simpleMessage("合理的授权"),
|
||||||
@@ -114,9 +120,13 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Show_more_logs": MessageLookupByLibrary.simpleMessage("显示更多日志"),
|
"Show_more_logs": MessageLookupByLibrary.simpleMessage("显示更多日志"),
|
||||||
"Sign_Event": MessageLookupByLibrary.simpleMessage("签名事件"),
|
"Sign_Event": MessageLookupByLibrary.simpleMessage("签名事件"),
|
||||||
"Stars": MessageLookupByLibrary.simpleMessage("保存书签"),
|
"Stars": MessageLookupByLibrary.simpleMessage("保存书签"),
|
||||||
|
"Streaming": MessageLookupByLibrary.simpleMessage("直播"),
|
||||||
"ThemeStyle": MessageLookupByLibrary.simpleMessage("主题类型"),
|
"ThemeStyle": MessageLookupByLibrary.simpleMessage("主题类型"),
|
||||||
|
"Tools": MessageLookupByLibrary.simpleMessage("工具"),
|
||||||
"Url": MessageLookupByLibrary.simpleMessage("链接"),
|
"Url": MessageLookupByLibrary.simpleMessage("链接"),
|
||||||
"WEB": MessageLookupByLibrary.simpleMessage("网页"),
|
"WEB": MessageLookupByLibrary.simpleMessage("网页"),
|
||||||
|
"Web_APPs": MessageLookupByLibrary.simpleMessage("网页应用"),
|
||||||
|
"Zaps": MessageLookupByLibrary.simpleMessage("Zaps"),
|
||||||
"a": MessageLookupByLibrary.simpleMessage("一个"),
|
"a": MessageLookupByLibrary.simpleMessage("一个"),
|
||||||
"auto": MessageLookupByLibrary.simpleMessage("自动"),
|
"auto": MessageLookupByLibrary.simpleMessage("自动"),
|
||||||
"detail": MessageLookupByLibrary.simpleMessage("详情"),
|
"detail": MessageLookupByLibrary.simpleMessage("详情"),
|
||||||
|
|||||||
@@ -1019,6 +1019,106 @@ class S {
|
|||||||
args: [],
|
args: [],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `Notes`
|
||||||
|
String get Notes {
|
||||||
|
return Intl.message(
|
||||||
|
'Notes',
|
||||||
|
name: 'Notes',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Long Form`
|
||||||
|
String get Long_Form {
|
||||||
|
return Intl.message(
|
||||||
|
'Long Form',
|
||||||
|
name: 'Long_Form',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Group Chat`
|
||||||
|
String get Group_Chat {
|
||||||
|
return Intl.message(
|
||||||
|
'Group Chat',
|
||||||
|
name: 'Group_Chat',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Tools`
|
||||||
|
String get Tools {
|
||||||
|
return Intl.message(
|
||||||
|
'Tools',
|
||||||
|
name: 'Tools',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Photos`
|
||||||
|
String get Photos {
|
||||||
|
return Intl.message(
|
||||||
|
'Photos',
|
||||||
|
name: 'Photos',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Streaming`
|
||||||
|
String get Streaming {
|
||||||
|
return Intl.message(
|
||||||
|
'Streaming',
|
||||||
|
name: 'Streaming',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Zaps`
|
||||||
|
String get Zaps {
|
||||||
|
return Intl.message(
|
||||||
|
'Zaps',
|
||||||
|
name: 'Zaps',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Marketplaces`
|
||||||
|
String get Marketplaces {
|
||||||
|
return Intl.message(
|
||||||
|
'Marketplaces',
|
||||||
|
name: 'Marketplaces',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `All`
|
||||||
|
String get All {
|
||||||
|
return Intl.message(
|
||||||
|
'All',
|
||||||
|
name: 'All',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Web APPs`
|
||||||
|
String get Web_APPs {
|
||||||
|
return Intl.message(
|
||||||
|
'Web APPs',
|
||||||
|
name: 'Web_APPs',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
||||||
|
|||||||
@@ -95,5 +95,15 @@
|
|||||||
"or": "or",
|
"or": "or",
|
||||||
"Login_with_Nesigner": "Login with Nesigner",
|
"Login_with_Nesigner": "Login with Nesigner",
|
||||||
"Login_fail": "Login_fail",
|
"Login_fail": "Login_fail",
|
||||||
"Delete": "Delete"
|
"Delete": "Delete",
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Long_Form": "Long Form",
|
||||||
|
"Group_Chat": "Group Chat",
|
||||||
|
"Tools": "Tools",
|
||||||
|
"Photos": "Photos",
|
||||||
|
"Streaming": "Streaming",
|
||||||
|
"Zaps": "Zaps",
|
||||||
|
"Marketplaces": "Marketplaces",
|
||||||
|
"All": "All",
|
||||||
|
"Web_APPs": "Web APPs"
|
||||||
}
|
}
|
||||||
@@ -95,5 +95,15 @@
|
|||||||
"or": "或者",
|
"or": "或者",
|
||||||
"Login_with_Nesigner": "使用 Nesigner 登录",
|
"Login_with_Nesigner": "使用 Nesigner 登录",
|
||||||
"Login_fail": "登录失败",
|
"Login_fail": "登录失败",
|
||||||
"Delete": "删除"
|
"Delete": "删除",
|
||||||
|
"Notes": "笔记",
|
||||||
|
"Long_Form": "长文本",
|
||||||
|
"Group_Chat": "群组聊天",
|
||||||
|
"Tools": "工具",
|
||||||
|
"Photos": "照片",
|
||||||
|
"Streaming": "直播",
|
||||||
|
"Zaps": "Zaps",
|
||||||
|
"Marketplaces": "市场",
|
||||||
|
"All": "全部",
|
||||||
|
"Web_APPs": "网页应用"
|
||||||
}
|
}
|
||||||
@@ -36,6 +36,7 @@ import 'package:nowser/router/index/index_router.dart';
|
|||||||
import 'package:nowser/router/keys/keys_router.dart';
|
import 'package:nowser/router/keys/keys_router.dart';
|
||||||
import 'package:nowser/router/me/me_router.dart';
|
import 'package:nowser/router/me/me_router.dart';
|
||||||
import 'package:nowser/router/setting/setting_router.dart';
|
import 'package:nowser/router/setting/setting_router.dart';
|
||||||
|
import 'package:nowser/router/web_apps/web_apps_router.dart';
|
||||||
import 'package:nowser/router/web_tabs_select/web_tabs_select_router.dart';
|
import 'package:nowser/router/web_tabs_select/web_tabs_select_router.dart';
|
||||||
import 'package:nowser/router/web_url_input/web_url_input_router.dart';
|
import 'package:nowser/router/web_url_input/web_url_input_router.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@@ -220,6 +221,7 @@ class _MyApp extends State<MyApp> {
|
|||||||
RouterPath.SETTING: (context) => SettingRouter(indexReload: reload),
|
RouterPath.SETTING: (context) => SettingRouter(indexReload: reload),
|
||||||
RouterPath.ABOUT_ME: (context) => AboutMeRouter(),
|
RouterPath.ABOUT_ME: (context) => AboutMeRouter(),
|
||||||
RouterPath.DOWNLOADS: (context) => DownloadsRouter(),
|
RouterPath.DOWNLOADS: (context) => DownloadsRouter(),
|
||||||
|
RouterPath.WEB_APPS: (context) => WebAppsRouter(),
|
||||||
};
|
};
|
||||||
|
|
||||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||||
|
|||||||
23
lib/router/web_apps/web_app_item.dart
Normal file
23
lib/router/web_apps/web_app_item.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
class WebAppItem {
|
||||||
|
String link;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
|
||||||
|
String desc;
|
||||||
|
|
||||||
|
String? image;
|
||||||
|
|
||||||
|
List<String> types;
|
||||||
|
|
||||||
|
WebAppItem(this.link, this.name, this.desc, this.types, {this.image});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
"link": link,
|
||||||
|
"name": name,
|
||||||
|
"desc": desc,
|
||||||
|
"image": image,
|
||||||
|
"types": types,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
98
lib/router/web_apps/web_app_item_component.dart
Normal file
98
lib/router/web_apps/web_app_item_component.dart
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:nowser/router/web_apps/web_app_item.dart';
|
||||||
|
|
||||||
|
import '../../const/base.dart';
|
||||||
|
|
||||||
|
class WebAppItemComponent extends StatefulWidget {
|
||||||
|
WebAppItem item;
|
||||||
|
|
||||||
|
Function(WebAppItem item)? onTap;
|
||||||
|
|
||||||
|
WebAppItemComponent(
|
||||||
|
this.item, {
|
||||||
|
this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() {
|
||||||
|
return _WebAppItemComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _WebAppItemComponent extends State<WebAppItemComponent> {
|
||||||
|
double IMAGE_WIDTH = 74;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var themeData = Theme.of(context);
|
||||||
|
var titleFontSize = themeData.textTheme.bodyLarge!.fontSize;
|
||||||
|
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.onTap != null) {
|
||||||
|
widget.onTap!(widget.item);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: Base.BASE_PADDING,
|
||||||
|
right: Base.BASE_PADDING,
|
||||||
|
bottom: Base.BASE_PADDING,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: IMAGE_WIDTH,
|
||||||
|
width: IMAGE_WIDTH,
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(14),
|
||||||
|
),
|
||||||
|
child: widget.item.image != null
|
||||||
|
? Image.network(
|
||||||
|
widget.item.image!,
|
||||||
|
height: IMAGE_WIDTH,
|
||||||
|
width: IMAGE_WIDTH,
|
||||||
|
)
|
||||||
|
: Icon(
|
||||||
|
Icons.public,
|
||||||
|
size: 70,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.only(left: Base.BASE_PADDING),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
child: Text(
|
||||||
|
widget.item.name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: titleFontSize,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
child: Text(
|
||||||
|
widget.item.desc,
|
||||||
|
style: TextStyle(
|
||||||
|
color: themeData.hintColor,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
lib/router/web_apps/web_app_types.dart
Normal file
10
lib/router/web_apps/web_app_types.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
class WebAppTypes {
|
||||||
|
static String NOTES = "notes";
|
||||||
|
static String LONG_FORM = "longForm";
|
||||||
|
static String GROUP_CHAT = "groupChat";
|
||||||
|
static String TOOLS = "tools";
|
||||||
|
static String PHOTOS = "photos";
|
||||||
|
static String STREAMING = "streaming";
|
||||||
|
static String ZAPS = "zaps";
|
||||||
|
static String Marketplaces = "marketplaces";
|
||||||
|
}
|
||||||
296
lib/router/web_apps/web_apps_router.dart
Normal file
296
lib/router/web_apps/web_apps_router.dart
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:developer';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:nostr_sdk/utils/platform_util.dart';
|
||||||
|
import 'package:nostr_sdk/utils/string_util.dart';
|
||||||
|
import 'package:nowser/component/cust_state.dart';
|
||||||
|
import 'package:nowser/const/base.dart';
|
||||||
|
import 'package:nowser/const/base_consts.dart';
|
||||||
|
import 'package:nowser/main.dart';
|
||||||
|
import 'package:nowser/router/web_apps/web_app_item_component.dart';
|
||||||
|
import 'package:nowser/util/router_util.dart';
|
||||||
|
|
||||||
|
import '../../component/appbar_back_btn_component.dart';
|
||||||
|
import '../../generated/l10n.dart';
|
||||||
|
import '../../util/dio_util.dart';
|
||||||
|
import 'web_app_item.dart';
|
||||||
|
import 'web_app_types.dart';
|
||||||
|
|
||||||
|
class WebAppsRouter extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() {
|
||||||
|
return WebAppsRouterState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WebAppsRouterState extends CustState<WebAppsRouter> {
|
||||||
|
late S s;
|
||||||
|
|
||||||
|
List<WebAppItem> items = [];
|
||||||
|
|
||||||
|
Map<String, int> selectedMap = {};
|
||||||
|
|
||||||
|
List<EnumObj> typeEnums = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget doBuild(BuildContext context) {
|
||||||
|
s = S.of(context);
|
||||||
|
var themeData = Theme.of(context);
|
||||||
|
|
||||||
|
if (typeEnums.isEmpty) {
|
||||||
|
typeEnums.add(EnumObj(WebAppTypes.NOTES, s.Notes));
|
||||||
|
typeEnums.add(EnumObj(WebAppTypes.LONG_FORM, s.Long_Form));
|
||||||
|
typeEnums.add(EnumObj(WebAppTypes.GROUP_CHAT, s.Group_Chat));
|
||||||
|
typeEnums.add(EnumObj(WebAppTypes.TOOLS, s.Tools));
|
||||||
|
typeEnums.add(EnumObj(WebAppTypes.PHOTOS, s.Photos));
|
||||||
|
typeEnums.add(EnumObj(WebAppTypes.STREAMING, s.Streaming));
|
||||||
|
typeEnums.add(EnumObj(WebAppTypes.ZAPS, s.Zaps));
|
||||||
|
typeEnums.add(EnumObj(WebAppTypes.Marketplaces, s.Marketplaces));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> list = [];
|
||||||
|
|
||||||
|
List<Widget> typeWidgetList = [];
|
||||||
|
typeWidgetList
|
||||||
|
.add(buildTypeWidget(EnumObj("all", s.All), selectedMap.isEmpty, () {
|
||||||
|
if (selectedMap.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
selectedMap.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
for (var typeEnum in typeEnums) {
|
||||||
|
var selected = selectedMap[typeEnum.value] != null;
|
||||||
|
typeWidgetList.add(buildTypeWidget(typeEnum, selected, () {
|
||||||
|
if (selected) {
|
||||||
|
setState(() {
|
||||||
|
selectedMap.remove(typeEnum.value);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
selectedMap[typeEnum.value] = 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
list.add(Container(
|
||||||
|
margin: const EdgeInsets.only(
|
||||||
|
top: Base.BASE_PADDING,
|
||||||
|
bottom: Base.BASE_PADDING,
|
||||||
|
),
|
||||||
|
child: Wrap(
|
||||||
|
children: typeWidgetList,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
List<WebAppItem> showItems = [];
|
||||||
|
if (selectedMap.isNotEmpty) {
|
||||||
|
for (var item in items) {
|
||||||
|
for (var typeValue in item.types) {
|
||||||
|
if (selectedMap[typeValue] != null) {
|
||||||
|
showItems.add(item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showItems.addAll(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> itemWidgetList = [];
|
||||||
|
if (PlatformUtil.isPC()) {
|
||||||
|
for (var i = 0; i < showItems.length; i += 2) {
|
||||||
|
var item = showItems[i];
|
||||||
|
if (i + 1 < showItems.length) {
|
||||||
|
var item1 = showItems[i + 1];
|
||||||
|
itemWidgetList.add(Container(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: WebAppItemComponent(item, onTap: onTap)),
|
||||||
|
Expanded(child: WebAppItemComponent(item1, onTap: onTap)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
itemWidgetList.add(Container(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: WebAppItemComponent(item, onTap: onTap)),
|
||||||
|
Expanded(child: Container()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (var item in showItems) {
|
||||||
|
itemWidgetList.add(WebAppItemComponent(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list.add(Expanded(
|
||||||
|
child: Container(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: itemWidgetList,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: AppbarBackBtnComponent(),
|
||||||
|
title: Text(
|
||||||
|
"Web APPs",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: themeData.textTheme.bodyLarge!.fontSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: list,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onTap(WebAppItem item) {
|
||||||
|
RouterUtil.back(context);
|
||||||
|
webProvider.addTab(url: item.link);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onReady(BuildContext context) async {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> load() async {
|
||||||
|
var str = await DioUtil.getStr(Base.WEB_APPS);
|
||||||
|
if (StringUtil.isNotBlank(str)) {
|
||||||
|
var jsonList = jsonDecode(str!);
|
||||||
|
if (jsonList is List) {
|
||||||
|
items.clear();
|
||||||
|
|
||||||
|
for (var jsonObj in jsonList) {
|
||||||
|
var link = jsonObj["link"];
|
||||||
|
var name = jsonObj["name"];
|
||||||
|
var desc = jsonObj["desc"];
|
||||||
|
var types = jsonObj["types"];
|
||||||
|
var image = jsonObj["image"];
|
||||||
|
|
||||||
|
// print(link);
|
||||||
|
// print(name);
|
||||||
|
// print(desc);
|
||||||
|
// print(types);
|
||||||
|
// print(types! is List);
|
||||||
|
// print(image);
|
||||||
|
|
||||||
|
if (StringUtil.isBlank(link) ||
|
||||||
|
StringUtil.isBlank(name) ||
|
||||||
|
StringUtil.isBlank(desc) ||
|
||||||
|
types is! List) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
items.add(WebAppItem(
|
||||||
|
link, name, desc, types.map((item) => item.toString()).toList(),
|
||||||
|
image: image));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildTypeWidget(EnumObj enumObj, bool selected, Function onTap) {
|
||||||
|
return Container(
|
||||||
|
child: GestureDetector(
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
child: Checkbox(
|
||||||
|
value: selected,
|
||||||
|
onChanged: (_) {
|
||||||
|
onTap();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
child: Text(enumObj.name),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
if (items.isEmpty) {
|
||||||
|
items.add(WebAppItem(
|
||||||
|
"https://app.flotilla.social/",
|
||||||
|
"Flotilla",
|
||||||
|
"Relay chat client",
|
||||||
|
[WebAppTypes.GROUP_CHAT],
|
||||||
|
image: "https://nowser.nostrmo.com/images/apps/flotilla.png",
|
||||||
|
));
|
||||||
|
items.add(WebAppItem(
|
||||||
|
"https://www.zapplepay.com/",
|
||||||
|
"Zapplepay",
|
||||||
|
"Zap from any client 🖕",
|
||||||
|
[WebAppTypes.TOOLS],
|
||||||
|
image: "https://nowser.nostrmo.com/images/apps/zapplepay.png",
|
||||||
|
));
|
||||||
|
items.add(WebAppItem(
|
||||||
|
"https://habla.news/",
|
||||||
|
"Habla",
|
||||||
|
"A long form content client for nostr notes",
|
||||||
|
[WebAppTypes.LONG_FORM],
|
||||||
|
image: "https://nowser.nostrmo.com/images/apps/habla.png",
|
||||||
|
));
|
||||||
|
items.add(WebAppItem(
|
||||||
|
"https://listr.lol/",
|
||||||
|
"Listr",
|
||||||
|
"Create nostr lists",
|
||||||
|
[WebAppTypes.TOOLS],
|
||||||
|
image: "https://nowser.nostrmo.com/images/apps/listr.png",
|
||||||
|
));
|
||||||
|
items.add(WebAppItem(
|
||||||
|
"https://groups.nip29.com/",
|
||||||
|
"Groups",
|
||||||
|
"A relay-based NIP-29 group chat client",
|
||||||
|
[WebAppTypes.GROUP_CHAT],
|
||||||
|
image: "https://nowser.nostrmo.com/images/apps/groups.png",
|
||||||
|
));
|
||||||
|
items.add(WebAppItem(
|
||||||
|
"https://lumilumi.app/",
|
||||||
|
"lumilumi",
|
||||||
|
"Switch between full and low-data modes — a flexible Nostr web client",
|
||||||
|
[WebAppTypes.NOTES],
|
||||||
|
image: "https://nowser.nostrmo.com/images/apps/lumilumi.ico",
|
||||||
|
));
|
||||||
|
items.add(WebAppItem(
|
||||||
|
"https://iris.to/",
|
||||||
|
"Iris",
|
||||||
|
"Simple and fast web client",
|
||||||
|
[WebAppTypes.NOTES],
|
||||||
|
image: "https://nowser.nostrmo.com/images/apps/iris.png",
|
||||||
|
));
|
||||||
|
|
||||||
|
// List<Map> jsonList = [];
|
||||||
|
// for (var item in items) {
|
||||||
|
// jsonList.add(item.toJson());
|
||||||
|
// }
|
||||||
|
// log(jsonEncode(jsonList));
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user