✨ Maintain basic messaging websocket
@ -2,7 +2,7 @@
|
|||||||
<application
|
<application
|
||||||
android:label="solian"
|
android:label="solian"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/launcher_icon">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
BIN
android/app/src/main/res/mipmap-hdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
assets/icon.png
Executable file
After Width: | Height: | Size: 69 KiB |
@ -541,7 +541,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
@ -598,7 +598,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 625 B |
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 958 B |
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 586 B After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 5.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 8.0 KiB |
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
|
import 'package:solian/providers/chat.dart';
|
||||||
import 'package:solian/providers/navigation.dart';
|
import 'package:solian/providers/navigation.dart';
|
||||||
import 'package:solian/router.dart';
|
import 'package:solian/router.dart';
|
||||||
import 'package:solian/utils/timeago.dart';
|
import 'package:solian/utils/timeago.dart';
|
||||||
@ -37,6 +38,7 @@ class SolianApp extends StatelessWidget {
|
|||||||
providers: [
|
providers: [
|
||||||
Provider(create: (_) => NavigationProvider()),
|
Provider(create: (_) => NavigationProvider()),
|
||||||
Provider(create: (_) => AuthProvider()),
|
Provider(create: (_) => AuthProvider()),
|
||||||
|
Provider(create: (_) => ChatProvider()),
|
||||||
],
|
],
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
|
23
lib/models/packet.dart
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
class NetworkPackage {
|
||||||
|
String method;
|
||||||
|
String? message;
|
||||||
|
Map<String, dynamic>? payload;
|
||||||
|
|
||||||
|
NetworkPackage({
|
||||||
|
required this.method,
|
||||||
|
this.message,
|
||||||
|
this.payload,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory NetworkPackage.fromJson(Map<String, dynamic> json) => NetworkPackage(
|
||||||
|
method: json["w"],
|
||||||
|
message: json["m"],
|
||||||
|
payload: json["p"],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"w": method,
|
||||||
|
"m": message,
|
||||||
|
"p": payload,
|
||||||
|
};
|
||||||
|
}
|
29
lib/providers/chat.dart
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:solian/providers/auth.dart';
|
||||||
|
import 'package:solian/utils/service_url.dart';
|
||||||
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
|
|
||||||
|
class ChatProvider {
|
||||||
|
bool isOpened = false;
|
||||||
|
|
||||||
|
Future<WebSocketChannel?> connect(AuthProvider auth) async {
|
||||||
|
if (auth.client == null) await auth.pickClient();
|
||||||
|
if (!await auth.isAuthorized()) return null;
|
||||||
|
|
||||||
|
await auth.refreshToken();
|
||||||
|
|
||||||
|
var ori = getRequestUri('messaging', '/api/unified');
|
||||||
|
var uri = Uri(
|
||||||
|
scheme: ori.scheme.replaceFirst('http', 'ws'),
|
||||||
|
host: ori.host,
|
||||||
|
path: ori.path,
|
||||||
|
queryParameters: {'tk': Uri.encodeComponent(auth.client!.credentials.accessToken)},
|
||||||
|
);
|
||||||
|
|
||||||
|
final channel = WebSocketChannel.connect(uri);
|
||||||
|
await channel.ready;
|
||||||
|
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -9,6 +8,7 @@ import 'package:solian/models/message.dart';
|
|||||||
import 'package:solian/models/pagination.dart';
|
import 'package:solian/models/pagination.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/utils/service_url.dart';
|
import 'package:solian/utils/service_url.dart';
|
||||||
|
import 'package:solian/widgets/chat/maintainer.dart';
|
||||||
import 'package:solian/widgets/chat/message.dart';
|
import 'package:solian/widgets/chat/message.dart';
|
||||||
import 'package:solian/widgets/chat/message_editor.dart';
|
import 'package:solian/widgets/chat/message_editor.dart';
|
||||||
import 'package:solian/widgets/indent_wrapper.dart';
|
import 'package:solian/widgets/indent_wrapper.dart';
|
||||||
@ -78,6 +78,14 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
return a.createdAt.difference(b.createdAt).inMinutes <= 5;
|
return a.createdAt.difference(b.createdAt).inMinutes <= 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addMessage(Message item) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
setState(() {
|
||||||
|
_pagingController.itemList?.insert(0, item);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
Future.delayed(Duration.zero, () {
|
Future.delayed(Duration.zero, () {
|
||||||
@ -94,35 +102,43 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
return IndentWrapper(
|
return IndentWrapper(
|
||||||
hideDrawer: true,
|
hideDrawer: true,
|
||||||
title: _channelMeta?.name ?? "Loading...",
|
title: _channelMeta?.name ?? "Loading...",
|
||||||
child: Column(
|
child: ChatMaintainer(
|
||||||
children: [
|
child: Column(
|
||||||
Expanded(
|
children: [
|
||||||
child: PagedListView<int, Message>(
|
Expanded(
|
||||||
pagingController: _pagingController,
|
child: PagedListView<int, Message>(
|
||||||
builderDelegate: PagedChildBuilderDelegate<Message>(
|
reverse: true,
|
||||||
itemBuilder: (context, item, index) {
|
pagingController: _pagingController,
|
||||||
bool isMerged = false, hasMerged = false;
|
builderDelegate: PagedChildBuilderDelegate<Message>(
|
||||||
if (index > 0) {
|
itemBuilder: (context, item, index) {
|
||||||
isMerged = getMessageMergeable(_pagingController.itemList?[index - 1], item);
|
bool isMerged = false, hasMerged = false;
|
||||||
}
|
if (index > 0) {
|
||||||
if (index + 1 < (_pagingController.itemList?.length ?? 0)) {
|
hasMerged = getMessageMergeable(_pagingController.itemList?[index - 1], item);
|
||||||
hasMerged = getMessageMergeable(item, _pagingController.itemList?[index + 1]);
|
}
|
||||||
}
|
if (index + 1 < (_pagingController.itemList?.length ?? 0)) {
|
||||||
return Container(
|
isMerged = getMessageMergeable(item, _pagingController.itemList?[index + 1]);
|
||||||
padding: EdgeInsets.only(
|
}
|
||||||
top: !isMerged ? 8 : 0,
|
return Container(
|
||||||
bottom: !hasMerged ? 8 : 0,
|
padding: EdgeInsets.only(
|
||||||
left: 12,
|
top: !isMerged ? 8 : 0,
|
||||||
right: 12,
|
bottom: !hasMerged ? 8 : 0,
|
||||||
),
|
left: 12,
|
||||||
child: ChatMessage(item: item, underMerged: isMerged),
|
right: 12,
|
||||||
);
|
),
|
||||||
},
|
child: ChatMessage(
|
||||||
|
key: Key('m${item.id}'),
|
||||||
|
item: item,
|
||||||
|
underMerged: isMerged,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
ChatMessageEditor(channel: widget.alias),
|
||||||
ChatMessageEditor(channel: widget.alias),
|
],
|
||||||
],
|
),
|
||||||
|
onNewMessage: (message) => addMessage(message),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
45
lib/widgets/chat/maintainer.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:solian/models/message.dart';
|
||||||
|
import 'package:solian/models/packet.dart';
|
||||||
|
import 'package:solian/providers/auth.dart';
|
||||||
|
import 'package:solian/providers/chat.dart';
|
||||||
|
|
||||||
|
class ChatMaintainer extends StatefulWidget {
|
||||||
|
final Widget child;
|
||||||
|
final Function(Message val) onNewMessage;
|
||||||
|
|
||||||
|
const ChatMaintainer({super.key, required this.child, required this.onNewMessage});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ChatMaintainer> createState() => _ChatMaintainerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ChatMaintainerState extends State<ChatMaintainer> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
Future.delayed(Duration.zero, () {
|
||||||
|
final auth = context.read<AuthProvider>();
|
||||||
|
final chat = context.read<ChatProvider>();
|
||||||
|
|
||||||
|
chat.connect(auth).then((snapshot) {
|
||||||
|
snapshot!.stream.listen((event) {
|
||||||
|
final result = NetworkPackage.fromJson(jsonDecode(event));
|
||||||
|
switch (result.method) {
|
||||||
|
case 'messages.new':
|
||||||
|
widget.onNewMessage(Message.fromJson(result.payload!));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return widget.child;
|
||||||
|
}
|
||||||
|
}
|
@ -46,7 +46,11 @@ class ChatMessage extends StatelessWidget {
|
|||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(width: 40),
|
const SizedBox(width: 40),
|
||||||
Expanded(child: contentPart),
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: [contentPart, renderAttachment()],
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,68 +1,68 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"info": {
|
||||||
{
|
"version": 1,
|
||||||
"size" : "16x16",
|
"author": "xcode"
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_16.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
},
|
||||||
{
|
"images": [
|
||||||
"size" : "16x16",
|
{
|
||||||
"idiom" : "mac",
|
"size": "16x16",
|
||||||
"filename" : "app_icon_32.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_16.png",
|
||||||
},
|
"scale": "1x"
|
||||||
{
|
},
|
||||||
"size" : "32x32",
|
{
|
||||||
"idiom" : "mac",
|
"size": "16x16",
|
||||||
"filename" : "app_icon_32.png",
|
"idiom": "mac",
|
||||||
"scale" : "1x"
|
"filename": "app_icon_32.png",
|
||||||
},
|
"scale": "2x"
|
||||||
{
|
},
|
||||||
"size" : "32x32",
|
{
|
||||||
"idiom" : "mac",
|
"size": "32x32",
|
||||||
"filename" : "app_icon_64.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_32.png",
|
||||||
},
|
"scale": "1x"
|
||||||
{
|
},
|
||||||
"size" : "128x128",
|
{
|
||||||
"idiom" : "mac",
|
"size": "32x32",
|
||||||
"filename" : "app_icon_128.png",
|
"idiom": "mac",
|
||||||
"scale" : "1x"
|
"filename": "app_icon_64.png",
|
||||||
},
|
"scale": "2x"
|
||||||
{
|
},
|
||||||
"size" : "128x128",
|
{
|
||||||
"idiom" : "mac",
|
"size": "128x128",
|
||||||
"filename" : "app_icon_256.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_128.png",
|
||||||
},
|
"scale": "1x"
|
||||||
{
|
},
|
||||||
"size" : "256x256",
|
{
|
||||||
"idiom" : "mac",
|
"size": "128x128",
|
||||||
"filename" : "app_icon_256.png",
|
"idiom": "mac",
|
||||||
"scale" : "1x"
|
"filename": "app_icon_256.png",
|
||||||
},
|
"scale": "2x"
|
||||||
{
|
},
|
||||||
"size" : "256x256",
|
{
|
||||||
"idiom" : "mac",
|
"size": "256x256",
|
||||||
"filename" : "app_icon_512.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_256.png",
|
||||||
},
|
"scale": "1x"
|
||||||
{
|
},
|
||||||
"size" : "512x512",
|
{
|
||||||
"idiom" : "mac",
|
"size": "256x256",
|
||||||
"filename" : "app_icon_512.png",
|
"idiom": "mac",
|
||||||
"scale" : "1x"
|
"filename": "app_icon_512.png",
|
||||||
},
|
"scale": "2x"
|
||||||
{
|
},
|
||||||
"size" : "512x512",
|
{
|
||||||
"idiom" : "mac",
|
"size": "512x512",
|
||||||
"filename" : "app_icon_1024.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_512.png",
|
||||||
}
|
"scale": "1x"
|
||||||
],
|
},
|
||||||
"info" : {
|
{
|
||||||
"version" : 1,
|
"size": "512x512",
|
||||||
"author" : "xcode"
|
"idiom": "mac",
|
||||||
}
|
"filename": "app_icon_1024.png",
|
||||||
}
|
"scale": "2x"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 480 B |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.5 KiB |
48
pubspec.lock
@ -41,6 +41,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
|
checked_yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: checked_yaml
|
||||||
|
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.3"
|
||||||
|
cli_util:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cli_util
|
||||||
|
sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.4.1"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -166,6 +182,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.0"
|
||||||
|
flutter_launcher_icons:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_launcher_icons
|
||||||
|
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.1"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -397,6 +421,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.7"
|
version: "0.6.7"
|
||||||
|
json_annotation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: json_annotation
|
||||||
|
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.8.1"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -962,6 +994,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "0.5.1"
|
||||||
|
web_socket_channel:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: web_socket_channel
|
||||||
|
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.5"
|
||||||
webview_flutter:
|
webview_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1018,6 +1058,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.5.0"
|
version: "6.5.0"
|
||||||
|
yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: yaml
|
||||||
|
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.3 <4.0.0"
|
dart: ">=3.3.3 <4.0.0"
|
||||||
flutter: ">=3.19.0"
|
flutter: ">=3.19.0"
|
||||||
|
20
pubspec.yaml
@ -57,6 +57,8 @@ dependencies:
|
|||||||
media_kit: ^1.1.10+1
|
media_kit: ^1.1.10+1
|
||||||
media_kit_libs_video: ^1.0.4
|
media_kit_libs_video: ^1.0.4
|
||||||
hive_flutter: ^1.1.0
|
hive_flutter: ^1.1.0
|
||||||
|
flutter_launcher_icons: ^0.13.1
|
||||||
|
web_socket_channel: ^2.4.5
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -111,3 +113,21 @@ flutter:
|
|||||||
#
|
#
|
||||||
# For details regarding fonts from package dependencies,
|
# For details regarding fonts from package dependencies,
|
||||||
# see https://flutter.dev/custom-fonts/#from-packages
|
# see https://flutter.dev/custom-fonts/#from-packages
|
||||||
|
|
||||||
|
flutter_launcher_icons:
|
||||||
|
android: "launcher_icon"
|
||||||
|
ios: true
|
||||||
|
image_path: "assets/icon.png"
|
||||||
|
min_sdk_android: 21
|
||||||
|
web:
|
||||||
|
generate: true
|
||||||
|
image_path: "assets/icon.png"
|
||||||
|
background_color: "#ffffff"
|
||||||
|
theme_color: "#4b5094"
|
||||||
|
windows:
|
||||||
|
generate: true
|
||||||
|
image_path: "assets/icon.png"
|
||||||
|
icon_size: 256
|
||||||
|
macos:
|
||||||
|
generate: true
|
||||||
|
image_path: "assets/icon.png"
|
BIN
web/favicon.png
Before Width: | Height: | Size: 917 B After Width: | Height: | Size: 480 B |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 29 KiB |
@ -3,8 +3,8 @@
|
|||||||
"short_name": "solian",
|
"short_name": "solian",
|
||||||
"start_url": ".",
|
"start_url": ".",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"background_color": "#0175C2",
|
"background_color": "#ffffff",
|
||||||
"theme_color": "#0175C2",
|
"theme_color": "#4b5094",
|
||||||
"description": "A new Flutter project.",
|
"description": "A new Flutter project.",
|
||||||
"orientation": "portrait-primary",
|
"orientation": "portrait-primary",
|
||||||
"prefer_related_applications": false,
|
"prefer_related_applications": false,
|
||||||
@ -32,4 +32,4 @@
|
|||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 13 KiB |