add filters

This commit is contained in:
otsmr 2025-03-23 00:56:29 +01:00
parent 14fbad280b
commit c2ce0ea2b1
18 changed files with 240 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View file

@ -32,6 +32,8 @@ class BackgroundLayerData extends Layer {
}); });
} }
class FilterLayerData extends Layer {}
/// Attributes used by [EmojiLayer] /// Attributes used by [EmojiLayer]
class EmojiLayerData extends Layer { class EmojiLayerData extends Layer {
String text; String text;

View file

@ -0,0 +1,81 @@
import 'package:flutter/material.dart';
import 'package:twonly/src/components/image_editor/data/layer.dart';
import 'package:twonly/src/components/image_editor/layers/filters/datetime_filter.dart';
import 'package:twonly/src/components/image_editor/layers/filters/image_filter.dart';
import 'package:twonly/src/components/image_editor/layers/filters/location_filter.dart';
/// Main layer
class FilterLayer extends StatefulWidget {
final FilterLayerData layerData;
// final VoidCallback? onUpdate;
const FilterLayer({
super.key,
required this.layerData,
// this.onUpdate,
});
@override
State<FilterLayer> createState() => _FilterLayerState();
}
class FilterSceleton extends StatelessWidget {
const FilterSceleton({super.key, this.child});
final Widget? child;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.transparent,
child: Stack(
children: [
Positioned.fill(child: Container()),
if (child != null) child!,
],
),
);
}
}
class FilterText extends StatelessWidget {
const FilterText(this.text, {super.key, this.fontSize = 24});
final String text;
final double fontSize;
@override
Widget build(BuildContext context) {
return Text(
text,
textAlign: TextAlign.start,
style: TextStyle(
fontSize: fontSize,
color: Colors.white,
shadows: [
Shadow(
color: const Color.fromARGB(122, 0, 0, 0),
blurRadius: 5.0,
)
],
),
);
}
}
class _FilterLayerState extends State<FilterLayer> {
@override
Widget build(BuildContext context) {
return PageView(
children: [
FilterSceleton(),
DateTimeFilter(),
LocationFilter(),
ImageFilter(imagePath: "random/lol.png"),
ImageFilter(imagePath: "random/hide_the_pain.png"),
ImageFilter(imagePath: "random/yolo.png"),
ImageFilter(imagePath: "random/chillen.png"),
ImageFilter(imagePath: "random/avocardio.png"),
ImageFilter(imagePath: "random/duck.png"),
],
);
}
}

View file

@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:twonly/src/components/image_editor/layers/filter_layer.dart';
class DateTimeFilter extends StatelessWidget {
const DateTimeFilter({super.key});
@override
Widget build(BuildContext context) {
String currentTime = DateFormat('HH:mm').format(DateTime.now());
String currentDate = DateFormat('dd.MM.yyyy').format(DateTime.now());
return FilterSceleton(
child: Positioned(
bottom: 80,
left: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FilterText(currentTime),
FilterText(currentDate),
],
),
),
);
}
}

View file

@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
import 'package:twonly/src/components/image_editor/layers/filter_layer.dart';
class ImageFilter extends StatelessWidget {
const ImageFilter({super.key, required this.imagePath});
final String imagePath;
@override
Widget build(BuildContext context) {
return FilterSceleton(
child: Positioned(
bottom: 50,
left: 10,
right: 10,
child: Center(
child: Image.asset(
"assets/filters/$imagePath",
height: 150,
),
),
),
);
}
}

View file

@ -0,0 +1,87 @@
import 'package:flutter/material.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/src/components/image_editor/layers/filter_layer.dart';
import 'package:twonly/src/components/image_editor/layers/filters/image_filter.dart';
import 'package:twonly/src/proto/api/server_to_client.pb.dart';
class LocationFilter extends StatefulWidget {
const LocationFilter({super.key});
@override
State<LocationFilter> createState() => _LocationFilterState();
}
Map<String, String> cities = {
"Frankfurt am Main": "germany_frankfurt_am_main.png",
};
Map<String, String> countries = {
"Germany": "germany.png",
};
class _LocationFilterState extends State<LocationFilter> {
String? selectedImage;
String overlayText = "";
Response_Location? location;
@override
void initState() {
super.initState();
initAsync();
}
Future initAsync() async {
final res = await apiProvider.getCurrentLocation();
if (res.isSuccess) {
location = res.value.location;
if (cities.containsKey(location!.city)) {
selectedImage = cities[location!.city];
overlayText = location!.city;
} else if (countries.containsKey(location!.county)) {
selectedImage = countries[location!.county];
overlayText = location!.county;
}
setState(() {});
}
}
@override
Widget build(BuildContext context) {
if (selectedImage != null) {
return Stack(
children: [
ImageFilter(imagePath: "location/${selectedImage!}"),
Positioned(
bottom: 55,
left: 0,
right: 0,
child: Center(
child: Text(overlayText),
),
)
],
);
}
if (location != null) {
return FilterSceleton(
child: Positioned(
bottom: 50,
left: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
FilterText(location!.city),
FilterText(location!.region),
FilterText(location!.county),
],
),
),
);
}
return Container();
}
}

View file

@ -3,6 +3,7 @@ import 'package:twonly/src/components/image_editor/data/layer.dart';
import 'package:twonly/src/components/image_editor/layers/background_layer.dart'; import 'package:twonly/src/components/image_editor/layers/background_layer.dart';
import 'package:twonly/src/components/image_editor/layers/draw_layer.dart'; import 'package:twonly/src/components/image_editor/layers/draw_layer.dart';
import 'package:twonly/src/components/image_editor/layers/emoji_layer.dart'; import 'package:twonly/src/components/image_editor/layers/emoji_layer.dart';
import 'package:twonly/src/components/image_editor/layers/filter_layer.dart';
import 'package:twonly/src/components/image_editor/layers/text_layer.dart'; import 'package:twonly/src/components/image_editor/layers/text_layer.dart';
/// View stacked layers (unbounded height, width) /// View stacked layers (unbounded height, width)
@ -27,6 +28,11 @@ class LayersViewer extends StatelessWidget {
onUpdate: onUpdate, onUpdate: onUpdate,
); );
}), }),
...layers.whereType<FilterLayerData>().map((layerItem) {
return FilterLayer(
layerData: layerItem,
);
}),
...layers ...layers
.where((layerItem) => .where((layerItem) =>
layerItem is EmojiLayerData || layerItem is DrawLayerData) layerItem is EmojiLayerData || layerItem is DrawLayerData)

View file

@ -56,7 +56,8 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
// today a message was already send -> update flame // today a message was already send -> update flame
updateFlame = true; updateFlame = true;
} }
} else if (contact.lastMessageReceived!.isAfter(startOfToday)) { } else if (contact.lastMessageReceived != null &&
contact.lastMessageReceived!.isAfter(startOfToday)) {
// today a message was already received -> update flame // today a message was already received -> update flame
updateFlame = true; updateFlame = true;
} }

View file

@ -337,6 +337,13 @@ class ApiProvider {
return await sendRequestSync(req); return await sendRequestSync(req);
} }
Future<Result> getCurrentLocation() async {
var get = ApplicationData_GetLocation();
var appData = ApplicationData()..getlocation = get;
var req = createClientToServerFromApplicationData(appData);
return await sendRequestSync(req);
}
Future<Result> triggerDownload(List<int> token, int offset) async { Future<Result> triggerDownload(List<int> token, int offset) async {
var get = ApplicationData_DownloadData() var get = ApplicationData_DownloadData()
..downloadToken = token ..downloadToken = token

View file

@ -246,6 +246,8 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
image: currentImage, image: currentImage,
)); ));
layers.add(FilterLayerData());
setState(() {}); setState(() {});
} }

View file

@ -89,4 +89,7 @@ flutter:
- assets/images/onboarding/ricky_the_greedy_racoon.png - assets/images/onboarding/ricky_the_greedy_racoon.png
- assets/animated_icons/ - assets/animated_icons/
- assets/animations/ - assets/animations/
- assets/filters/
- assets/filters/location/
- assets/filters/random/