moving more dependencies into the subrepo
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run

This commit is contained in:
otsmr 2026-08-22 20:31:38 +02:00
parent 1027856691
commit 4183ebd8e6
21 changed files with 656 additions and 264 deletions

1
.gitignore vendored
View file

@ -56,3 +56,4 @@ devtools_options.yaml
rust/target rust/target
rust_dependencies/target rust_dependencies/target
fastlane/repo/status/running.json fastlane/repo/status/running.json
.cache/

@ -1 +1 @@
Subproject commit 32882a31904a0c1ffd38974bf5158ceee0f3ecb7 Subproject commit d1d70e1559a67bd5c4336547d215a03260153b00

204
dependencies.py Normal file
View file

@ -0,0 +1,204 @@
import yaml
import os
import shutil
import subprocess
import argparse
import sys
def print_blue(text):
BLUE = '\x1b[34m'
RESET = '\x1b[0m'
print(f"{BLUE}{text}{RESET}")
def print_yellow(text):
YELLOW = '\x1b[33m'
RESET = '\x1b[0m'
print(f"{YELLOW}{text}{RESET}")
def get_git_head(repo_path='.'):
result = subprocess.run(
['git', 'rev-parse', 'HEAD'],
cwd=repo_path,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
check=False
)
if result.returncode != 0:
raise RuntimeError(f"git error: {result.stderr.strip()}")
return result.stdout.strip()
def get_default_branch(repo_path='.'):
result = subprocess.run(
['git', 'symbolic-ref', 'refs/remotes/origin/HEAD'],
cwd=repo_path,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
check=False
)
if result.returncode == 0:
return result.stdout.strip().split('/')[-1]
return 'main'
def integrate_package(folder_name, data, cache_dir, out_dir):
repo_url = data['git']
keep_list = ["lib", "LICENSE", "pubspec.yaml", "android", "ios", "darwin"]
if "keep" in data:
keep_list += [item.rstrip('/') for item in data['keep']]
print(f"Processing {folder_name}...")
cache_path = os.path.join(cache_dir, folder_name)
if not os.path.exists(cache_path):
subprocess.run(["git", "clone", repo_url, cache_path], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
else:
result = subprocess.run(["git", "fetch", "--all"], check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=cache_path)
if result.returncode != 0:
print_yellow(f"Warning: Could not fetch updates for {folder_name}. You might be offline.")
if "commit" in data:
commit_hash = data["commit"]
subprocess.run(["git", "checkout", commit_hash], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=cache_path)
elif "tag" in data:
tag_name = data["tag"]
subprocess.run(["git", "checkout", tag_name], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=cache_path)
else:
print_yellow(f"Warning: No commit or tag specified for {folder_name}. Using default branch.")
default_branch = get_default_branch(cache_path)
subprocess.run(["git", "checkout", default_branch], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=cache_path)
subprocess.run(["git", "pull"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=cache_path)
last_commit_hash = get_git_head(cache_path)
data["commit"] = last_commit_hash
print_blue(f"Recorded commit {last_commit_hash} for {folder_name}")
results = [] # List of (pkg_name, version)
if "subpackages" in data:
packages_to_extract = data["subpackages"]
else:
packages_to_extract = [{"name": folder_name, "path": data.get("path", "")}]
for pkg in packages_to_extract:
pkg_name = pkg["name"]
subpath = pkg.get("path", "")
out_path = os.path.join(out_dir, pkg_name)
if os.path.exists(out_path):
shutil.rmtree(out_path)
os.makedirs(out_path)
package_src_path = os.path.join(cache_path, subpath) if subpath else cache_path
for item in keep_list:
src_item = os.path.join(package_src_path, item)
dst_item = os.path.join(out_path, item)
if os.path.exists(src_item):
os.makedirs(os.path.dirname(dst_item), exist_ok=True)
if os.path.isdir(src_item):
shutil.copytree(src_item, dst_item, dirs_exist_ok=True)
else:
shutil.copy2(src_item, dst_item)
version = "any"
try:
pubspec_path = os.path.join(package_src_path, "pubspec.yaml")
if os.path.exists(pubspec_path):
with open(pubspec_path, "r") as f:
ps = yaml.safe_load(f)
if ps and isinstance(ps, dict):
version = ps.get("version", "any")
except Exception as e:
print_yellow(f"Warning: Could not read version from {pkg_name}/pubspec.yaml")
results.append((pkg_name, version))
return results
def main():
parser = argparse.ArgumentParser(description="Update specific or all repositories.")
parser.add_argument('repo_name', nargs='?', default=None, help="Name of the repository to update (optional)")
args = parser.parse_args()
with open("dependencies.yaml", "r") as f:
config = yaml.safe_load(f)
cache_dir = config.get('cache', './.cache')
out_dir = config.get('outdir', './dependencies')
deps = config.get('dependencies', {})
if not os.path.exists(cache_dir):
os.makedirs(cache_dir)
if not os.path.exists(out_dir):
os.makedirs(out_dir)
repos_to_update = [args.repo_name] if args.repo_name else list(deps.keys())
pubspec_overrides = []
pubspec_deps = []
def process_deps_recursive(deps_dict, to_update=None):
for name, data in deps_dict.items():
if to_update is None or name in to_update:
extracted_packages = integrate_package(name, data, cache_dir, out_dir)
for pkg_name, version in extracted_packages:
pubspec_overrides.append(f" {pkg_name}:\n path: {out_dir}/{pkg_name}\n")
if version and version != "any":
pubspec_deps.append(f" {pkg_name}: ^{version}\n")
else:
pubspec_deps.append(f" {pkg_name}: any\n")
if "dependencies" in data:
# If we updated the parent, we should update children? Or if no args provided, update all.
# Actually, the original logic updated children automatically if parent is updated.
process_deps_recursive(data["dependencies"], None if (to_update is None or name in to_update) else [])
process_deps_recursive(deps, repos_to_update if args.repo_name else None)
def sort_dependencies(d):
sorted_d = {k: d[k] for k in sorted(d.keys())}
for k, v in sorted_d.items():
if "dependencies" in v and isinstance(v["dependencies"], dict):
v["dependencies"] = sort_dependencies(v["dependencies"])
return sorted_d
if "dependencies" in config:
config["dependencies"] = sort_dependencies(config["dependencies"])
with open("dependencies.yaml", "w") as f:
yaml.safe_dump(config, f, sort_keys=False)
# Update pubspec.yaml
if not args.repo_name:
with open("pubspec.yaml", "r") as f:
pubspec_lines = f.readlines()
start_marker_overrides = "## --- Start Managed Dependency Overrides ---"
end_marker_overrides = "## --- End Managed Dependency Overrides ---"
start_marker_deps = "## --- Start Managed Dependencies ---"
end_marker_deps = "## --- End Managed Dependencies ---"
try:
start_idx_overrides = next(i for i, line in enumerate(pubspec_lines) if line.strip() == start_marker_overrides)
end_idx_overrides = next(i for i, line in enumerate(pubspec_lines) if line.strip() == end_marker_overrides)
# Update overrides section
new_lines = pubspec_lines[:start_idx_overrides + 1] + pubspec_overrides + pubspec_lines[end_idx_overrides:]
# Now find the deps markers in the updated lines
start_idx_deps = next(i for i, line in enumerate(new_lines) if line.strip() == start_marker_deps)
end_idx_deps = next(i for i, line in enumerate(new_lines) if line.strip() == end_marker_deps)
# Update dependencies section
final_lines = new_lines[:start_idx_deps + 1] + pubspec_deps + new_lines[end_idx_deps:]
with open("pubspec.yaml", "w") as f:
f.writelines(final_lines)
print_blue("Updated pubspec.yaml successfully.")
except ValueError as e:
print_yellow("Error: Could not find professional markers in pubspec.yaml.")
sys.exit(1)
if __name__ == "__main__":
main()

109
dependencies.yaml Normal file
View file

@ -0,0 +1,109 @@
cache: ./.cache
outdir: ./dependencies
dependencies:
audio_waveforms:
git: https://github.com/SimformSolutionsPvtLtd/audio_waveforms.git
tag: 2.0.2
avatar_maker:
git: https://github.com/RoadTripMoustache/avatar_maker.git
tag: 1.5.0
keep:
- assets/icons
blurhash_dart:
git: https://github.com/justacid/blurhash-dart.git
tag: v1.2.1
exif:
git: https://github.com/bigflood/dartexif.git
dependencies:
sprintf:
git: https://github.com/Naddiseo/dart-sprintf.git
commit: f1e74f2f4c339d983f9d011b4ba1df4ec8b8857c
commit: bf170d5639f0b6fcb0947060cf8bd7b623df9069
flutter_blurhash:
git: https://github.com/fluttercommunity/flutter_blurhash.git
commit: c5cdec4986432e835bb91f5ce00564534450cdc7
flutter_markdown_plus:
git: https://github.com/foresightmobile/flutter_markdown_plus.git
commit: dc1185c933fbf9dba559ef6c91586ff1503be3ee
flutter_packages:
git: https://github.com/otsmr/flutter-packages.git
subpackages:
- name: video_player
path: packages/video_player/video_player
- name: video_player_android
path: packages/video_player/video_player_android
- name: video_player_avfoundation
path: packages/video_player/video_player_avfoundation
- name: camera_android_camerax
path: packages/camera/camera_android_camerax
commit: bb0e9f500828f3117a6ea96b898eaee3710e43d9
flutter_sharing_intent:
git: https://github.com/bhagat-techind/flutter_sharing_intent.git
commit: aa1672f547d6579585fa27df0b28ffa2a2544aaa
hand_signature:
git: https://github.com/RomanBase/hand_signature.git
commit: 1beedb164d093643365b0832277c377353c7464f
hashlib:
git: https://github.com/bitanon/hashlib.git
replace:
- - abstract class MACHashBase
- abstract mixin class MACHashBase
dependencies:
hashlib_codecs:
git: https://github.com/bitanon/hashlib_codecs.git
commit: 2a966c37c3b9b1f5541ae88e99ab34acf3fc968b
commit: bc9c2f8dd7bbc72f47ccab0ce1111d40259c49bc
image:
git: https://github.com/brendan-duncan/image.git
tag: v4.9.2
introduction_screen:
git: https://github.com/Pyozer/introduction_screen.git
dependencies:
dots_indicator:
git: https://github.com/Pyozer/dots_indicator.git
commit: 508f5883ac79bdbc10254092de3f28f571d261cd
commit: 4a90e557630b28834479ed9c64a9d2d0185d8e48
libsignal_protocol_dart:
git: https://github.com/MixinNetwork/libsignal_protocol_dart.git
dependencies:
adaptive_number:
git: https://github.com/lemoony/adaptive_number_dart
commit: ea9178fdd4d82ac45cf0ec966ac870dae661124f
ed25519_edwards:
git: https://github.com/Tougee/ed25519.git
commit: 7353ba759ea9f4646cbf481c2ef949625c8ce4cf
optional:
git: https://github.com/tonio-ramirez/optional.dart.git
commit: 71c638891ce4f2aff35c7387727989f31f9d877d
pointycastle:
git: https://github.com/bcgit/pc-dart.git
commit: bbd8569f68a7fccbdf0b92d0b44a9219c126c8dd
x25519:
git: https://github.com/Tougee/curve25519.git
commit: ecb1d357714537bba6e276ef45f093846d4beaee
commit: c95a1586057022acdbb9c76b1692d94cc549bcc7
lottie:
git: https://github.com/xvrh/lottie-flutter.git
commit: 127bc29f2c6bd8b32ec4064a09e54e6b31cd0a88
mutex:
git: https://github.com/hoylen/dart-mutex.git
commit: 84ca903a3ac863735e3228c75a212133621f680f
photo_view:
git: https://github.com/bluefireteam/photo_view.git
commit: a13ca2fc387a3fb1276126959e092c44d0029987
pro_video_editor:
git: https://github.com/hm21/pro_video_editor.git
tag: v2.11.3
qr_flutter:
git: https://github.com/theyakka/qr.flutter.git
dependencies:
qr:
git: https://github.com/kevmoo/qr.dart.git
commit: 7b1e9665ca976f484e7975356cf26fc7a0ccf02e
commit: d5e7206396105d643113618290bbcc755d05f492
restart_app:
git: https://github.com/gabrimatic/restart_app
commit: 66897cb67e235bab85421647bfae036acb4438cb
screen_protector:
git: https://github.com/prongbang/screen_protector.git
commit: 019c04d622d7b610d2903d3a347edc3ba76a6ed0

View file

@ -23,7 +23,6 @@ class UserData {
String username; String username;
String displayName; String displayName;
String? avatarSvg; String? avatarSvg;
String? avatarJson;
@JsonKey(defaultValue: 0) @JsonKey(defaultValue: 0)
int appVersion = 0; int appVersion = 0;

View file

@ -16,7 +16,6 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) =>
appVersion: (json['appVersion'] as num?)?.toInt() ?? 0, appVersion: (json['appVersion'] as num?)?.toInt() ?? 0,
) )
..avatarSvg = json['avatarSvg'] as String? ..avatarSvg = json['avatarSvg'] as String?
..avatarJson = json['avatarJson'] as String?
..avatarCounter = (json['avatarCounter'] as num?)?.toInt() ?? 0 ..avatarCounter = (json['avatarCounter'] as num?)?.toInt() ?? 0
..isDeveloper = json['isDeveloper'] as bool? ?? false ..isDeveloper = json['isDeveloper'] as bool? ?? false
..deviceId = (json['deviceId'] as num?)?.toInt() ?? 0 ..deviceId = (json['deviceId'] as num?)?.toInt() ?? 0
@ -129,7 +128,6 @@ Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
'username': instance.username, 'username': instance.username,
'displayName': instance.displayName, 'displayName': instance.displayName,
'avatarSvg': instance.avatarSvg, 'avatarSvg': instance.avatarSvg,
'avatarJson': instance.avatarJson,
'appVersion': instance.appVersion, 'appVersion': instance.appVersion,
'avatarCounter': instance.avatarCounter, 'avatarCounter': instance.avatarCounter,
'isDeveloper': instance.isDeveloper, 'isDeveloper': instance.isDeveloper,

View file

@ -5,6 +5,7 @@ import 'dart:ui' as ui;
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:mutex/mutex.dart';
import 'package:twonly/globals.dart'; import 'package:twonly/globals.dart';
import 'package:twonly/locator.dart'; import 'package:twonly/locator.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
@ -114,11 +115,14 @@ File currentUserAvatarFile(int avatarCounter) {
return File('${avatarsDirectory.path}/user_$avatarCounter.png'); return File('${avatarsDirectory.path}/user_$avatarCounter.png');
} }
final _avatarMutex = Mutex();
Future<String?> getUserAvatar() async { Future<String?> getUserAvatar() async {
if (userService.currentUser.avatarSvg == null) { if (userService.currentUser.avatarSvg == null) {
return null; return null;
} }
return _avatarMutex.protect(() async {
final avatarCounter = userService.currentUser.avatarCounter; final avatarCounter = userService.currentUser.avatarCounter;
final file = currentUserAvatarFile(avatarCounter); final file = currentUserAvatarFile(avatarCounter);
if (file.existsSync()) { if (file.existsSync()) {
@ -135,8 +139,9 @@ Future<String?> getUserAvatar() async {
final byteData = await image.toByteData(format: ui.ImageByteFormat.png); final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
final pngBytes = byteData!.buffer.asUint8List(); final pngBytes = byteData!.buffer.asUint8List();
await file.writeAsBytes(pngBytes); await file.writeAsBytes(pngBytes, flush: true);
pictureInfo.picture.dispose(); pictureInfo.picture.dispose();
return file.path; return file.path;
});
} }

View file

@ -0,0 +1,148 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
class CachedNetworkImage extends StatefulWidget {
const CachedNetworkImage({
required this.imageUrl,
super.key,
this.width,
this.height,
this.fit,
this.placeholder,
this.errorWidget,
});
final String imageUrl;
final double? width;
final double? height;
final BoxFit? fit;
final Widget Function(BuildContext, String)? placeholder;
final Widget Function(BuildContext, String, dynamic)? errorWidget;
@override
State<CachedNetworkImage> createState() => _CachedNetworkImageState();
}
class _CachedNetworkImageState extends State<CachedNetworkImage> {
File? _imageFile;
bool _isLoading = true;
dynamic _error;
static bool _hasCleanedUp = false;
@override
void initState() {
super.initState();
_loadImage();
}
@override
void didUpdateWidget(CachedNetworkImage oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.imageUrl != widget.imageUrl) {
_loadImage();
}
}
Future<void> _loadImage() async {
if (!mounted) return;
setState(() {
_isLoading = true;
_error = null;
});
try {
final cacheDir = await getTemporaryDirectory();
final urlHash = md5.convert(utf8.encode(widget.imageUrl)).toString();
final file = File('${cacheDir.path}/custom_cached_image_$urlHash');
if (!_hasCleanedUp) {
_hasCleanedUp = true;
unawaited(_cleanupOldFiles(cacheDir)); // Run asynchronously
}
if (file.existsSync()) {
if (mounted) {
setState(() {
_imageFile = file;
_isLoading = false;
});
}
return;
}
final client = HttpClient();
final request = await client.getUrl(Uri.parse(widget.imageUrl));
final response = await request.close();
if (response.statusCode == 200) {
await response.pipe(file.openWrite());
if (mounted) {
setState(() {
_imageFile = file;
_isLoading = false;
});
}
} else {
throw Exception('Failed to load image: ${response.statusCode}');
}
} catch (e) {
if (mounted) {
setState(() {
_error = e;
_isLoading = false;
});
}
}
}
Future<void> _cleanupOldFiles(Directory cacheDir) async {
try {
final files = cacheDir.listSync();
final now = DateTime.now();
for (final f in files) {
if (f is File && f.path.contains('custom_cached_image_')) {
final stat = f.statSync();
if (now.difference(stat.modified).inDays >= 7) {
await f.delete();
}
}
}
} catch (_) {
// Ignore cleanup errors
}
}
@override
Widget build(BuildContext context) {
if (_isLoading) {
if (widget.placeholder != null) {
return widget.placeholder!(context, widget.imageUrl);
}
return SizedBox(width: widget.width, height: widget.height);
}
if (_error != null || _imageFile == null) {
if (widget.errorWidget != null) {
return widget.errorWidget!(context, widget.imageUrl, _error);
}
return SizedBox(width: widget.width, height: widget.height);
}
return Image.file(
_imageFile!,
width: widget.width,
height: widget.height,
fit: widget.fit,
errorBuilder: (context, error, stackTrace) {
if (widget.errorWidget != null) {
return widget.errorWidget!(context, widget.imageUrl, error);
}
return SizedBox(width: widget.width, height: widget.height);
},
);
}
}

View file

@ -1,5 +1,5 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:twonly/src/visual/components/cached_network_image.dart';
import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/filter.layer.dart'; import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/filter.layer.dart';
class ImageFilter extends StatelessWidget { class ImageFilter extends StatelessWidget {

View file

@ -1,7 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/visual/components/cached_network_image.dart';
import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart'; import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart';
class CustomLinkCard extends StatelessWidget { class CustomLinkCard extends StatelessWidget {

View file

@ -1,7 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/visual/components/cached_network_image.dart';
import 'package:twonly/src/visual/loader/three_rotating_dots.loader.dart'; import 'package:twonly/src/visual/loader/three_rotating_dots.loader.dart';
import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart'; import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart';

View file

@ -1,7 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/visual/components/cached_network_image.dart';
// Assuming the same Metadata import structure // Assuming the same Metadata import structure
import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart'; import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart';

View file

@ -1,7 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/visual/components/cached_network_image.dart';
import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart'; import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart';
class YouTubePostCard extends StatelessWidget { class YouTubePostCard extends StatelessWidget {

View file

@ -19,8 +19,8 @@ import 'package:twonly/src/visual/components/emoji_picker.bottom.dart';
import 'package:twonly/src/visual/context_menu/context_menu.helper.dart'; import 'package:twonly/src/visual/context_menu/context_menu.helper.dart';
import 'package:twonly/src/visual/elements/my_button.element.dart'; import 'package:twonly/src/visual/elements/my_button.element.dart';
import 'package:twonly/src/visual/views/camera/share_image_editor_components/layer_data.dart'; import 'package:twonly/src/visual/views/camera/share_image_editor_components/layer_data.dart';
import 'package:twonly/src/visual/views/chats/message_info.view.dart';
import 'package:twonly/src/visual/views/chats/chat_messages_components/chat_list_entry.dart'; import 'package:twonly/src/visual/views/chats/chat_messages_components/chat_list_entry.dart';
import 'package:twonly/src/visual/views/chats/message_info.view.dart';
import 'package:twonly/src/visual/views/memories/synchronized_viewer.view.dart'; import 'package:twonly/src/visual/views/memories/synchronized_viewer.view.dart';
class MessageContextMenu extends StatelessWidget { class MessageContextMenu extends StatelessWidget {

View file

@ -1,9 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/visual/components/cached_network_image.dart';
import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/filters/stickers.dart'; import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/filters/stickers.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';

View file

@ -1,8 +1,8 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:twonly/locator.dart'; import 'package:twonly/locator.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/visual/components/cached_network_image.dart';
import 'package:twonly/src/visual/elements/reactive_tap_feedback.element.dart'; import 'package:twonly/src/visual/elements/reactive_tap_feedback.element.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';

View file

@ -31,10 +31,9 @@ class _ModifyAvatarViewState extends State<ModifyAvatarView> {
} }
} }
Future<void> updateUserAvatar(String json, String svg) async { Future<void> updateUserAvatar(String svg) async {
await UserService.update( await UserService.update(
(u) => u (u) => u
..avatarJson = json
..avatarSvg = svg ..avatarSvg = svg
..avatarCounter = u.avatarCounter + 1, ..avatarCounter = u.avatarCounter + 1,
); );
@ -104,9 +103,8 @@ class _ModifyAvatarViewState extends State<ModifyAvatarView> {
Future<void> storeAvatarAndExit() async { Future<void> storeAvatarAndExit() async {
await _avatarMakerController.saveAvatarSVG(); await _avatarMakerController.saveAvatarSVG();
final json = _avatarMakerController.getJsonOptionsSync();
final svg = _avatarMakerController.getAvatarSVGSync(); final svg = _avatarMakerController.getAvatarSVGSync();
await updateUserAvatar(json, svg); await updateUserAvatar(svg);
if (mounted) { if (mounted) {
Navigator.pop(context, true); Navigator.pop(context, true);
} }
@ -118,8 +116,8 @@ class _ModifyAvatarViewState extends State<ModifyAvatarView> {
canPop: false, canPop: false,
onPopInvokedWithResult: (didPop, result) async { onPopInvokedWithResult: (didPop, result) async {
if (didPop) return; if (didPop) return;
if (_avatarMakerController.getJsonOptionsSync() != if (_avatarMakerController.getAvatarSVGSync() !=
userService.currentUser.avatarJson) { userService.currentUser.avatarSvg) {
// there where changes // there where changes
final shouldPop = await _showBackDialog() ?? false; final shouldPop = await _showBackDialog() ?? false;
if (context.mounted && shouldPop) { if (context.mounted && shouldPop) {

View file

@ -18,7 +18,7 @@ packages:
source: hosted source: hosted
version: "1.3.68" version: "1.3.68"
adaptive_number: adaptive_number:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "dependencies/adaptive_number" path: "dependencies/adaptive_number"
relative: true relative: true
@ -91,19 +91,17 @@ packages:
audio_waveforms: audio_waveforms:
dependency: "direct main" dependency: "direct main"
description: description:
name: audio_waveforms path: "dependencies/audio_waveforms"
sha256: "03b3430ecf430a2e90185518a228c02be3d26653c62dd931e50d671213a6dbc8" relative: true
url: "https://pub.dev" source: path
source: hosted
version: "2.0.2" version: "2.0.2"
avatar_maker: avatar_maker:
dependency: "direct main" dependency: "direct main"
description: description:
name: avatar_maker path: "dependencies/avatar_maker"
sha256: ca182e33343846427da68fc226325f630063da2de2f0bdb49e683f0c843b80c2 relative: true
url: "https://pub.dev" source: path
source: hosted version: "1.5.0"
version: "0.4.0"
background_downloader: background_downloader:
dependency: "direct main" dependency: "direct main"
description: description:
@ -115,10 +113,9 @@ packages:
blurhash_dart: blurhash_dart:
dependency: "direct main" dependency: "direct main"
description: description:
name: blurhash_dart path: "dependencies/blurhash_dart"
sha256: "43955b6c2e30a7d440028d1af0fa185852f3534b795cc6eb81fbf397b464409f" relative: true
url: "https://pub.dev" source: path
source: hosted
version: "1.2.1" version: "1.2.1"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
@ -184,30 +181,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.12.5" version: "8.12.5"
cached_network_image:
dependency: "direct main"
description:
name: cached_network_image
sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916"
url: "https://pub.dev"
source: hosted
version: "3.4.1"
cached_network_image_platform_interface:
dependency: transitive
description:
name: cached_network_image_platform_interface
sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829"
url: "https://pub.dev"
source: hosted
version: "4.1.1"
cached_network_image_web:
dependency: transitive
description:
name: cached_network_image_web
sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
camera: camera:
dependency: "direct main" dependency: "direct main"
description: description:
@ -217,14 +190,12 @@ packages:
source: hosted source: hosted
version: "0.12.0+1" version: "0.12.0+1"
camera_android_camerax: camera_android_camerax:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "packages/camera/camera_android_camerax" path: "dependencies/camera_android_camerax"
ref: e83fb3a27d4da2c37a3c8acbf2486283965b4f69 relative: true
resolved-ref: e83fb3a27d4da2c37a3c8acbf2486283965b4f69 source: path
url: "https://github.com/otsmr/flutter-packages.git" version: "0.7.4+6"
source: git
version: "0.7.1+2"
camera_avfoundation: camera_avfoundation:
dependency: transitive dependency: transitive
description: description:
@ -237,10 +208,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: camera_platform_interface name: camera_platform_interface
sha256: "98cfc9357e04bad617671b4c1f78a597f25f08003089dd94050709ae54effc63" sha256: "4524ca6eb4176b066864036ad4fe02c3e4863e63b77eadc21a5bf56824f43498"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.12.0" version: "2.13.1"
camera_web: camera_web:
dependency: transitive dependency: transitive
description: description:
@ -410,7 +381,7 @@ packages:
source: hosted source: hosted
version: "8.1.0" version: "8.1.0"
dots_indicator: dots_indicator:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "dependencies/dots_indicator" path: "dependencies/dots_indicator"
relative: true relative: true
@ -441,7 +412,7 @@ packages:
source: hosted source: hosted
version: "0.3.0" version: "0.3.0"
ed25519_edwards: ed25519_edwards:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "dependencies/ed25519_edwards" path: "dependencies/ed25519_edwards"
relative: true relative: true
@ -628,14 +599,6 @@ packages:
relative: true relative: true
source: path source: path
version: "0.9.1" version: "0.9.1"
flutter_cache_manager:
dependency: transitive
description:
name: flutter_cache_manager
sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
url: "https://pub.dev"
source: hosted
version: "3.4.1"
flutter_driver: flutter_driver:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -986,7 +949,7 @@ packages:
source: path source: path
version: "2.3.0" version: "2.3.0"
hashlib_codecs: hashlib_codecs:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "dependencies/hashlib_codecs" path: "dependencies/hashlib_codecs"
relative: true relative: true
@ -1035,11 +998,10 @@ packages:
image: image:
dependency: "direct main" dependency: "direct main"
description: description:
name: image path: "dependencies/image"
sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce relative: true
url: "https://pub.dev" source: path
source: hosted version: "4.9.2"
version: "4.8.0"
image_picker: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1306,6 +1268,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.13.0" version: "0.13.0"
material_symbols_icons:
dependency: transitive
description:
name: material_symbols_icons
sha256: bd513edc2bc9b034108d5518c48cf5cebbb67d0653728cc452368cb27ca80bb0
url: "https://pub.dev"
source: hosted
version: "4.2960.0"
meta: meta:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1361,16 +1331,8 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "9.3.0" version: "9.3.0"
octo_image:
dependency: transitive
description:
name: octo_image
sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
optional: optional:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "dependencies/optional" path: "dependencies/optional"
relative: true relative: true
@ -1552,7 +1514,7 @@ packages:
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
pointycastle: pointycastle:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "dependencies/pointycastle" path: "dependencies/pointycastle"
relative: true relative: true
@ -1577,11 +1539,10 @@ packages:
pro_video_editor: pro_video_editor:
dependency: "direct main" dependency: "direct main"
description: description:
name: pro_video_editor path: "dependencies/pro_video_editor"
sha256: cfed1424b3ca3d5981cc81efdd20b844c995c0ad2818e185eb5bc06a8674f728 relative: true
url: "https://pub.dev" source: path
source: hosted version: "2.11.3"
version: "1.14.2"
process: process:
dependency: transitive dependency: transitive
description: description:
@ -1623,7 +1584,7 @@ packages:
source: hosted source: hosted
version: "1.5.0" version: "1.5.0"
qr: qr:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "dependencies/qr" path: "dependencies/qr"
relative: true relative: true
@ -1658,14 +1619,6 @@ packages:
relative: true relative: true
source: path source: path
version: "0.0.1" version: "0.0.1"
rxdart:
dependency: transitive
description:
name: rxdart
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
url: "https://pub.dev"
source: hosted
version: "0.28.0"
screen_protector: screen_protector:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1815,52 +1768,12 @@ packages:
source: hosted source: hosted
version: "1.10.2" version: "1.10.2"
sprintf: sprintf:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "dependencies/sprintf" path: "dependencies/sprintf"
relative: true relative: true
source: path source: path
version: "7.0.0" version: "7.0.0"
sqflite:
dependency: transitive
description:
name: sqflite
sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
url: "https://pub.dev"
source: hosted
version: "2.4.2"
sqflite_android:
dependency: transitive
description:
name: sqflite_android
sha256: "881e28efdcc9950fd8e9bb42713dcf1103e62a2e7168f23c9338d82db13dec40"
url: "https://pub.dev"
source: hosted
version: "2.4.2+3"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6"
url: "https://pub.dev"
source: hosted
version: "2.5.6"
sqflite_darwin:
dependency: transitive
description:
name: sqflite_darwin
sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
sqflite_platform_interface:
dependency: transitive
description:
name: sqflite_platform_interface
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
sqlcipher_flutter_libs: sqlcipher_flutter_libs:
dependency: transitive dependency: transitive
description: description:
@ -1933,14 +1846,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.1" version: "0.3.1"
synchronized:
dependency: transitive
description:
name: synchronized
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
url: "https://pub.dev"
source: hosted
version: "3.4.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@ -2088,35 +1993,32 @@ packages:
video_player: video_player:
dependency: "direct main" dependency: "direct main"
description: description:
name: video_player path: "dependencies/video_player"
sha256: "48a7bdaa38a3d50ec10c78627abdbfad863fdf6f0d6e08c7c3c040cfd80ae36f" relative: true
url: "https://pub.dev" source: path
source: hosted version: "2.14.0"
version: "2.11.1"
video_player_android: video_player_android:
dependency: transitive dependency: "direct main"
description: description:
name: video_player_android path: "dependencies/video_player_android"
sha256: "877a6c7ba772456077d7bfd71314629b3fe2b73733ce503fc77c3314d43a0ca0" relative: true
url: "https://pub.dev" source: path
source: hosted version: "2.12.0"
version: "2.9.5"
video_player_avfoundation: video_player_avfoundation:
dependency: transitive dependency: "direct main"
description: description:
name: video_player_avfoundation path: "dependencies/video_player_avfoundation"
sha256: af0e5b8a7a4876fb37e7cc8cb2a011e82bb3ecfa45844ef672e32cb14a1f259e relative: true
url: "https://pub.dev" source: path
source: hosted version: "2.11.0"
version: "2.9.4"
video_player_platform_interface: video_player_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: video_player_platform_interface name: video_player_platform_interface
sha256: "57c5d73173f76d801129d0531c2774052c5a7c11ccb962f1830630decd9f24ec" sha256: "92c0fbabe20c788e71fd10d26cea998d0d253282e65d145aed0818731cf593ce"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.6.0" version: "6.9.0"
video_player_web: video_player_web:
dependency: transitive dependency: transitive
description: description:
@ -2222,7 +2124,7 @@ packages:
source: hosted source: hosted
version: "0.9.1+1" version: "0.9.1+1"
x25519: x25519:
dependency: "direct overridden" dependency: "direct main"
description: description:
path: "dependencies/x25519" path: "dependencies/x25519"
relative: true relative: true

View file

@ -37,7 +37,6 @@ dependencies:
path_provider: ^2.1.5 path_provider: ^2.1.5
url_launcher: ^6.3.2 url_launcher: ^6.3.2
vector_graphics: ^1.1.19 vector_graphics: ^1.1.19
video_player: ^2.10.1
in_app_purchase: ^3.3.0 in_app_purchase: ^3.3.0
go_router: ^17.1.0 go_router: ^17.1.0
@ -72,34 +71,13 @@ dependencies:
# Overwritten by self-controlled repository # Overwritten by self-controlled repository
emoji_picker_flutter: ^4.3.0 emoji_picker_flutter: ^4.3.0
# Packages which got overwritten using the twonly-app-dependencies repository
# Idea: Every change goes though a git commit, where every change can be reviewed.
restart_app: ^1.3.2
photo_view: ^0.15.0
hashlib: ^2.0.0
libsignal_protocol_dart: ^0.7.4
lottie: ^3.3.1
mutex: ^3.1.0
introduction_screen: ^4.0.0
qr_flutter: ^4.1.0
hand_signature: ^3.0.3
flutter_sharing_intent: ^2.0.4
screen_protector: ^1.5.1
flutter_markdown_plus: ^1.0.7
exif: ^3.3.0
flutter_blurhash: ^0.9.1
# With high download. (But should be checked nonetheless.) # With high download. (But should be checked nonetheless.)
app_links: ^7.0.0 # 1.6 mio app_links: ^7.0.0 # 1.6 mio
image: ^4.3.0 # 3.3 mio
flutter_secure_storage: ^10.3.1 # 1.85 mio flutter_secure_storage: ^10.3.1 # 1.85 mio
permission_handler: ^12.0.0+1 # 2 mio permission_handler: ^12.0.0+1 # 2 mio
# Not yet checked # Not yet checked
audio_waveforms: ^2.0.2
avatar_maker: ^0.4.0
background_downloader: ^9.4.0 background_downloader: ^9.4.0
cached_network_image: ^3.4.1
cryptography_flutter_plus: ^3.0.0 cryptography_flutter_plus: ^3.0.0
cryptography_plus: ^3.0.0 cryptography_plus: ^3.0.0
flutter_android_volume_keydown: ^1.0.1 flutter_android_volume_keydown: ^1.0.1
@ -109,60 +87,47 @@ dependencies:
photo_manager: ^3.9.0 photo_manager: ^3.9.0
google_mlkit_barcode_scanning: ^0.14.1 google_mlkit_barcode_scanning: ^0.14.1
google_mlkit_face_detection: ^0.13.1 google_mlkit_face_detection: ^0.13.1
pro_video_editor: ^1.6.1
rust_lib_twonly: rust_lib_twonly:
path: rust_builder path: rust_builder
flutter_rust_bridge: 2.12.0 flutter_rust_bridge: 2.12.0
## --- Start Managed Dependencies ---
audio_waveforms: ^2.0.2
avatar_maker: ^1.5.0
blurhash_dart: ^1.2.1 blurhash_dart: ^1.2.1
exif: ^3.3.0
sprintf: ^7.0.0
flutter_blurhash: ^0.9.1
flutter_markdown_plus: ^1.0.7
video_player: ^2.14.0
video_player_android: ^2.12.0
video_player_avfoundation: ^2.11.0
camera_android_camerax: ^0.7.4+6
flutter_sharing_intent: ^2.0.4
hand_signature: ^3.1.0+2
hashlib: ^2.3.0
hashlib_codecs: ^3.0.1
image: ^4.9.2
introduction_screen: ^4.0.0
dots_indicator: ^4.0.1
libsignal_protocol_dart: ^0.8.0
adaptive_number: ^1.0.0
ed25519_edwards: ^0.3.1
optional: ^6.1.0+1
pointycastle: ^4.0.0
x25519: ^0.1.1
lottie: ^3.5.1
mutex: ^3.1.0
photo_view: ^0.15.0
pro_video_editor: ^2.11.3
qr_flutter: ^4.1.0
qr: ^3.1.0-wip
restart_app: ^1.7.3
screen_protector: ^1.5.1
## --- End Managed Dependencies ---
dependency_overrides: dependency_overrides:
dots_indicator:
path: ./dependencies/dots_indicator
restart_app:
path: ./dependencies/restart_app
hashlib:
path: ./dependencies/hashlib
introduction_screen:
path: ./dependencies/introduction_screen
libsignal_protocol_dart:
path: ./dependencies/libsignal_protocol_dart
flutter_sharing_intent:
path: ./dependencies/flutter_sharing_intent
lottie:
path: ./dependencies/lottie
mutex:
path: ./dependencies/mutex
photo_view:
path: ./dependencies/photo_view
qr:
path: ./dependencies/qr
adaptive_number:
path: ./dependencies/adaptive_number
ed25519_edwards:
path: ./dependencies/ed25519_edwards
hand_signature:
path: ./dependencies/hand_signature
hashlib_codecs:
path: ./dependencies/hashlib_codecs
optional:
path: ./dependencies/optional
pointycastle:
path: ./dependencies/pointycastle
x25519:
path: ./dependencies/x25519
qr_flutter:
path: ./dependencies/qr_flutter
screen_protector:
path: ./dependencies/screen_protector
flutter_markdown_plus:
path: ./dependencies/flutter_markdown_plus
camera_android_camerax:
# path: ../flutter-packages/packages/camera/camera_android_camerax
git:
url: https://github.com/otsmr/flutter-packages.git
path: packages/camera/camera_android_camerax
ref: e83fb3a27d4da2c37a3c8acbf2486283965b4f69
emoji_picker_flutter: emoji_picker_flutter:
# Fixes the issue with recent emojis (solved by https://github.com/Fintasys/emoji_picker_flutter/pull/238) # Fixes the issue with recent emojis (solved by https://github.com/Fintasys/emoji_picker_flutter/pull/238)
# Using override until this gets merged. # Using override until this gets merged.
@ -173,12 +138,74 @@ dependency_overrides:
git: git:
url: https://github.com/yenchieh/flutter_android_volume_keydown.git url: https://github.com/yenchieh/flutter_android_volume_keydown.git
ref: fix/lStar-not-found-error ref: fix/lStar-not-found-error
## --- Start Managed Dependency Overrides ---
audio_waveforms:
path: ./dependencies/audio_waveforms
avatar_maker:
path: ./dependencies/avatar_maker
blurhash_dart:
path: ./dependencies/blurhash_dart
exif: exif:
path: ./dependencies/exif path: ./dependencies/exif
sprintf: sprintf:
path: ./dependencies/sprintf path: ./dependencies/sprintf
flutter_blurhash: flutter_blurhash:
path: ./dependencies/flutter_blurhash path: ./dependencies/flutter_blurhash
flutter_markdown_plus:
path: ./dependencies/flutter_markdown_plus
video_player:
path: ./dependencies/video_player
video_player_android:
path: ./dependencies/video_player_android
video_player_avfoundation:
path: ./dependencies/video_player_avfoundation
camera_android_camerax:
path: ./dependencies/camera_android_camerax
flutter_sharing_intent:
path: ./dependencies/flutter_sharing_intent
hand_signature:
path: ./dependencies/hand_signature
hashlib:
path: ./dependencies/hashlib
hashlib_codecs:
path: ./dependencies/hashlib_codecs
image:
path: ./dependencies/image
introduction_screen:
path: ./dependencies/introduction_screen
dots_indicator:
path: ./dependencies/dots_indicator
libsignal_protocol_dart:
path: ./dependencies/libsignal_protocol_dart
adaptive_number:
path: ./dependencies/adaptive_number
ed25519_edwards:
path: ./dependencies/ed25519_edwards
optional:
path: ./dependencies/optional
pointycastle:
path: ./dependencies/pointycastle
x25519:
path: ./dependencies/x25519
lottie:
path: ./dependencies/lottie
mutex:
path: ./dependencies/mutex
photo_view:
path: ./dependencies/photo_view
pro_video_editor:
path: ./dependencies/pro_video_editor
qr_flutter:
path: ./dependencies/qr_flutter
qr:
path: ./dependencies/qr
restart_app:
path: ./dependencies/restart_app
screen_protector:
path: ./dependencies/screen_protector
## --- End Managed Dependency Overrides ---
dev_dependencies: dev_dependencies:
build_runner: ^2.4.15 build_runner: ^2.4.15

View file

@ -1,5 +1,6 @@
import 'dart:io';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:pro_video_editor/core/platform/io/io_helper.dart';
import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parse_link.dart'; import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parse_link.dart';
import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart'; import 'package:twonly/src/visual/views/camera/share_image_editor_components/layers/link_preview/parser/base.dart';

View file

@ -3,7 +3,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:twonly/src/visual/elements/better_text.element.dart'; import 'package:twonly/src/visual/elements/better_text.element.dart';
void main() { void main() {
testWidgets('BetterText parses URLs correctly', (WidgetTester tester) async { testWidgets('BetterText parses URLs correctly', (tester) async {
const text = const text =
'Test: (https://google.com) and another link https://example.com/#fragment, plus www.test.com. Also check https://wikipedia.org/wiki/Test_(disambiguation) !'; 'Test: (https://google.com) and another link https://example.com/#fragment, plus www.test.com. Also check https://wikipedia.org/wiki/Test_(disambiguation) !';