mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 17:48:40 +00:00
add time selection when sending
This commit is contained in:
parent
5675437bc0
commit
d3bc0dc135
16 changed files with 218 additions and 184 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'package:fixnum/fixnum.dart';
|
import 'package:fixnum/fixnum.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/components/flame.dart';
|
import 'package:twonly/src/components/flame.dart';
|
||||||
import 'package:twonly/src/components/headline.dart';
|
import 'package:twonly/src/components/headline.dart';
|
||||||
import 'package:twonly/src/components/initialsavatar.dart';
|
import 'package:twonly/src/components/initialsavatar.dart';
|
||||||
|
|
@ -29,7 +29,7 @@ class BestFriendsSelector extends StatelessWidget {
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
HeadLineComponent(AppLocalizations.of(context)!.shareImageBestFriends),
|
HeadLineComponent(context.lang.shareImageBestFriends),
|
||||||
Column(
|
Column(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
|
|
|
||||||
|
|
@ -5,24 +5,38 @@ class ActionButton extends StatelessWidget {
|
||||||
final VoidCallback? onPressed;
|
final VoidCallback? onPressed;
|
||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
final Color? color;
|
final Color? color;
|
||||||
|
final String tooltipText;
|
||||||
|
final bool disable;
|
||||||
|
|
||||||
const ActionButton(this.icon, {super.key, this.onPressed, this.color});
|
const ActionButton(this.icon,
|
||||||
|
{super.key,
|
||||||
|
this.onPressed,
|
||||||
|
this.color,
|
||||||
|
required this.tooltipText,
|
||||||
|
this.disable = false});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return IconButton(
|
return Tooltip(
|
||||||
icon: FaIcon(
|
message: tooltipText,
|
||||||
icon,
|
child: IconButton(
|
||||||
size: 30,
|
icon: FaIcon(
|
||||||
color: color ?? Colors.white,
|
icon,
|
||||||
shadows: [
|
size: 30,
|
||||||
Shadow(
|
color: disable
|
||||||
color: const Color.fromARGB(122, 0, 0, 0),
|
? const Color.fromARGB(154, 255, 255, 255)
|
||||||
blurRadius: 5.0,
|
: color ?? Colors.white,
|
||||||
)
|
shadows: [
|
||||||
],
|
Shadow(
|
||||||
|
color: const Color.fromARGB(122, 0, 0, 0),
|
||||||
|
blurRadius: 5.0,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (!disable && onPressed != null) onPressed!();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
onPressed: onPressed,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:hand_signature/signature.dart';
|
||||||
import 'package:screenshot/screenshot.dart';
|
import 'package:screenshot/screenshot.dart';
|
||||||
import 'package:twonly/src/components/image_editor/action_button.dart';
|
import 'package:twonly/src/components/image_editor/action_button.dart';
|
||||||
import 'package:twonly/src/components/image_editor/data/layer.dart';
|
import 'package:twonly/src/components/image_editor/data/layer.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
class DrawLayer extends StatefulWidget {
|
class DrawLayer extends StatefulWidget {
|
||||||
final DrawLayerData layerData;
|
final DrawLayerData layerData;
|
||||||
|
|
@ -106,6 +107,7 @@ class _DrawLayerState extends State<DrawLayer> {
|
||||||
children: [
|
children: [
|
||||||
ActionButton(
|
ActionButton(
|
||||||
FontAwesomeIcons.check,
|
FontAwesomeIcons.check,
|
||||||
|
tooltipText: context.lang.imageEditorDrawOk,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
widget.layerData.isEditing = false;
|
widget.layerData.isEditing = false;
|
||||||
},
|
},
|
||||||
|
|
@ -113,6 +115,7 @@ class _DrawLayerState extends State<DrawLayer> {
|
||||||
Expanded(child: Container()),
|
Expanded(child: Container()),
|
||||||
ActionButton(
|
ActionButton(
|
||||||
FontAwesomeIcons.arrowRotateLeft,
|
FontAwesomeIcons.arrowRotateLeft,
|
||||||
|
tooltipText: context.lang.undo,
|
||||||
color: widget.layerData.control.paths.isNotEmpty
|
color: widget.layerData.control.paths.isNotEmpty
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: Colors.white.withAlpha(80),
|
: Colors.white.withAlpha(80),
|
||||||
|
|
@ -125,6 +128,7 @@ class _DrawLayerState extends State<DrawLayer> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ActionButton(
|
ActionButton(
|
||||||
|
tooltipText: context.lang.redo,
|
||||||
FontAwesomeIcons.arrowRotateRight,
|
FontAwesomeIcons.arrowRotateRight,
|
||||||
color: undoList.isNotEmpty
|
color: undoList.isNotEmpty
|
||||||
? Colors.white
|
? Colors.white
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,7 @@ class _TextViewState extends State<TextLayer> {
|
||||||
},
|
},
|
||||||
child: ActionButton(
|
child: ActionButton(
|
||||||
FontAwesomeIcons.trashCan,
|
FontAwesomeIcons.trashCan,
|
||||||
|
tooltipText: "",
|
||||||
color: deleteLayer ? Colors.red : Colors.white,
|
color: deleteLayer ? Colors.red : Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import 'package:provider/provider.dart';
|
||||||
import 'package:twonly/src/model/json/message.dart';
|
import 'package:twonly/src/model/json/message.dart';
|
||||||
import 'package:twonly/src/model/messages_model.dart';
|
import 'package:twonly/src/model/messages_model.dart';
|
||||||
import 'package:twonly/src/providers/download_change_provider.dart';
|
import 'package:twonly/src/providers/download_change_provider.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
enum MessageSendState {
|
enum MessageSendState {
|
||||||
received,
|
received,
|
||||||
|
|
@ -44,29 +44,29 @@ class MessageSendStateIcon extends StatelessWidget {
|
||||||
switch (message.getSendState()) {
|
switch (message.getSendState()) {
|
||||||
case MessageSendState.receivedOpened:
|
case MessageSendState.receivedOpened:
|
||||||
icon = Icon(Icons.crop_square, size: 14, color: color);
|
icon = Icon(Icons.crop_square, size: 14, color: color);
|
||||||
text = AppLocalizations.of(context)!.messageSendState_Received;
|
text = context.lang.messageSendState_Received;
|
||||||
break;
|
break;
|
||||||
case MessageSendState.sendOpened:
|
case MessageSendState.sendOpened:
|
||||||
icon = FaIcon(FontAwesomeIcons.paperPlane, size: 12, color: color);
|
icon = FaIcon(FontAwesomeIcons.paperPlane, size: 12, color: color);
|
||||||
text = AppLocalizations.of(context)!.messageSendState_Opened;
|
text = context.lang.messageSendState_Opened;
|
||||||
break;
|
break;
|
||||||
case MessageSendState.received:
|
case MessageSendState.received:
|
||||||
icon = Icon(Icons.square_rounded, size: 14, color: color);
|
icon = Icon(Icons.square_rounded, size: 14, color: color);
|
||||||
text = AppLocalizations.of(context)!.messageSendState_Received;
|
text = context.lang.messageSendState_Received;
|
||||||
break;
|
break;
|
||||||
case MessageSendState.send:
|
case MessageSendState.send:
|
||||||
icon = FaIcon(FontAwesomeIcons.solidPaperPlane, size: 12, color: color);
|
icon = FaIcon(FontAwesomeIcons.solidPaperPlane, size: 12, color: color);
|
||||||
text = AppLocalizations.of(context)!.messageSendState_Send;
|
text = context.lang.messageSendState_Send;
|
||||||
break;
|
break;
|
||||||
case MessageSendState.sending:
|
case MessageSendState.sending:
|
||||||
case MessageSendState.receiving:
|
case MessageSendState.receiving:
|
||||||
icon = loaderIcon;
|
icon = loaderIcon;
|
||||||
text = AppLocalizations.of(context)!.messageSendState_Sending;
|
text = context.lang.messageSendState_Sending;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!message.isDownloaded) {
|
if (!message.isDownloaded) {
|
||||||
text = AppLocalizations.of(context)!.messageSendState_TapToLoad;
|
text = context.lang.messageSendState_TapToLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDownloading = false;
|
bool isDownloading = false;
|
||||||
|
|
@ -78,7 +78,7 @@ class MessageSendStateIcon extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDownloading) {
|
if (isDownloading) {
|
||||||
text = AppLocalizations.of(context)!.messageSendState_Loading;
|
text = context.lang.messageSendState_Loading;
|
||||||
icon = loaderIcon;
|
icon = loaderIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class NotificationBadge extends StatelessWidget {
|
class NotificationBadge extends StatelessWidget {
|
||||||
final int count;
|
final String count;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
const NotificationBadge(
|
const NotificationBadge(
|
||||||
|
|
@ -9,25 +9,29 @@ class NotificationBadge extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (count == 0) return child;
|
if (count == "0") return child;
|
||||||
|
bool infinity = count == "∞";
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
child,
|
child,
|
||||||
Positioned(
|
Positioned(
|
||||||
right: 5,
|
right: 3,
|
||||||
top: 0,
|
top: 0,
|
||||||
child: Container(
|
child: SizedBox(
|
||||||
padding: EdgeInsets.all(5.0), // Add some padding
|
height: 18,
|
||||||
decoration: BoxDecoration(
|
width: 18,
|
||||||
color: Colors.red, // Background color
|
child: CircleAvatar(
|
||||||
shape: BoxShape.circle, // Make it circular
|
backgroundColor: Colors.red,
|
||||||
),
|
child: Center(
|
||||||
child: Center(
|
child: Transform.rotate(
|
||||||
child: Text(
|
angle: infinity ? 90 * (3.141592653589793 / 180) : 0,
|
||||||
count.toString(),
|
child: Text(
|
||||||
style: TextStyle(
|
infinity ? "8" : count,
|
||||||
color: Colors.white, // Text color
|
style: TextStyle(
|
||||||
fontSize: 10,
|
color: Colors.white, // Text color
|
||||||
|
fontSize: 10,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,16 @@
|
||||||
"messageSendState_Sending": "Sending",
|
"messageSendState_Sending": "Sending",
|
||||||
"messageSendState_TapToLoad": "Tap to load",
|
"messageSendState_TapToLoad": "Tap to load",
|
||||||
"messageSendState_Loading": "Downloading",
|
"messageSendState_Loading": "Downloading",
|
||||||
|
"imageEditorDrawOk": "Take drawing",
|
||||||
|
"undo": "Undo",
|
||||||
|
"redo": "Redo",
|
||||||
|
"close": "Close",
|
||||||
|
"switchFrontAndBackCamera": "Switch between front and back camera.",
|
||||||
|
"addTextItem": "Text",
|
||||||
|
"protectAsARealTwonly": "Send as real twonly!",
|
||||||
|
"addDrawing": "Drawing",
|
||||||
|
"addEmoji": "Emoji",
|
||||||
|
"toogleFlashLight": "Toggle the flash light",
|
||||||
"chatListDetailTitle": "Your chat with {username}",
|
"chatListDetailTitle": "Your chat with {username}",
|
||||||
"searchUsernameNotFoundLong": "\"{username}\" is not a twonly user. Please check the username and try again.",
|
"searchUsernameNotFoundLong": "\"{username}\" is not a twonly user. Please check the username and try again.",
|
||||||
"errorUnknown": "An unexpected error has occurred. Please try again later.",
|
"errorUnknown": "An unexpected error has occurred. Please try again later.",
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,8 @@ Future encryptAndUploadMediaFile(Int64 target, Uint8List imageBytes) async {
|
||||||
await uploadMediaFile(messageId, target, encryptBytes);
|
await uploadMediaFile(messageId, target, encryptBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future sendImage(List<Int64> userIds, Uint8List imageBytes) async {
|
Future sendImage(List<Int64> userIds, Uint8List imageBytes, bool isRealTwonly,
|
||||||
|
int maxShowTime) async {
|
||||||
// 1. set notifier provider
|
// 1. set notifier provider
|
||||||
|
|
||||||
Uint8List? imageBytesCompressed = await getCompressedImage(imageBytes);
|
Uint8List? imageBytesCompressed = await getCompressedImage(imageBytes);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,10 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:twonly/src/proto/api/error.pb.dart';
|
import 'package:twonly/src/proto/api/error.pb.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
extension LocalizationExtension on BuildContext {
|
||||||
|
AppLocalizations get lang => AppLocalizations.of(this)!;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> writeLogToFile(LogRecord record) async {
|
Future<void> writeLogToFile(LogRecord record) async {
|
||||||
final directory = await getApplicationDocumentsDirectory();
|
final directory = await getApplicationDocumentsDirectory();
|
||||||
final logFile = File('${directory.path}/app.log');
|
final logFile = File('${directory.path}/app.log');
|
||||||
|
|
@ -57,31 +61,31 @@ Uint8List getRandomUint8List(int length) {
|
||||||
String errorCodeToText(BuildContext context, ErrorCode code) {
|
String errorCodeToText(BuildContext context, ErrorCode code) {
|
||||||
switch (code.toString()) {
|
switch (code.toString()) {
|
||||||
case "Unknown":
|
case "Unknown":
|
||||||
return AppLocalizations.of(context)!.errorUnknown;
|
return context.lang.errorUnknown;
|
||||||
case "BadRequest":
|
case "BadRequest":
|
||||||
return AppLocalizations.of(context)!.errorBadRequest;
|
return context.lang.errorBadRequest;
|
||||||
case "TooManyRequests":
|
case "TooManyRequests":
|
||||||
return AppLocalizations.of(context)!.errorTooManyRequests;
|
return context.lang.errorTooManyRequests;
|
||||||
case "InternalError":
|
case "InternalError":
|
||||||
return AppLocalizations.of(context)!.errorInternalError;
|
return context.lang.errorInternalError;
|
||||||
case "InvalidInvitationCode":
|
case "InvalidInvitationCode":
|
||||||
return AppLocalizations.of(context)!.errorInvalidInvitationCode;
|
return context.lang.errorInvalidInvitationCode;
|
||||||
case "UsernameAlreadyTaken":
|
case "UsernameAlreadyTaken":
|
||||||
return AppLocalizations.of(context)!.errorUsernameAlreadyTaken;
|
return context.lang.errorUsernameAlreadyTaken;
|
||||||
case "SignatureNotValid":
|
case "SignatureNotValid":
|
||||||
return AppLocalizations.of(context)!.errorSignatureNotValid;
|
return context.lang.errorSignatureNotValid;
|
||||||
case "UsernameNotFound":
|
case "UsernameNotFound":
|
||||||
return AppLocalizations.of(context)!.errorUsernameNotFound;
|
return context.lang.errorUsernameNotFound;
|
||||||
case "UsernameNotValid":
|
case "UsernameNotValid":
|
||||||
return AppLocalizations.of(context)!.errorUsernameNotValid;
|
return context.lang.errorUsernameNotValid;
|
||||||
case "InvalidPublicKey":
|
case "InvalidPublicKey":
|
||||||
return AppLocalizations.of(context)!.errorInvalidPublicKey;
|
return context.lang.errorInvalidPublicKey;
|
||||||
case "SessionAlreadyAuthenticated":
|
case "SessionAlreadyAuthenticated":
|
||||||
return AppLocalizations.of(context)!.errorSessionAlreadyAuthenticated;
|
return context.lang.errorSessionAlreadyAuthenticated;
|
||||||
case "SessionNotAuthenticated":
|
case "SessionNotAuthenticated":
|
||||||
return AppLocalizations.of(context)!.errorSessionNotAuthenticated;
|
return context.lang.errorSessionNotAuthenticated;
|
||||||
case "OnlyOneSessionAllowed":
|
case "OnlyOneSessionAllowed":
|
||||||
return AppLocalizations.of(context)!.errorOnlyOneSessionAllowed;
|
return context.lang.errorOnlyOneSessionAllowed;
|
||||||
default:
|
default:
|
||||||
return code.toString(); // Fallback for unrecognized keys
|
return code.toString(); // Fallback for unrecognized keys
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:camerawesome/camerawesome_plugin.dart';
|
import 'package:camerawesome/camerawesome_plugin.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/components/image_editor/action_button.dart';
|
import 'package:twonly/src/components/image_editor/action_button.dart';
|
||||||
import 'package:twonly/src/components/media_view_sizing.dart';
|
import 'package:twonly/src/components/media_view_sizing.dart';
|
||||||
import 'package:twonly/src/components/permissions_view.dart';
|
import 'package:twonly/src/components/permissions_view.dart';
|
||||||
|
|
@ -176,6 +177,8 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ActionButton(
|
ActionButton(
|
||||||
FontAwesomeIcons.repeat,
|
FontAwesomeIcons.repeat,
|
||||||
|
tooltipText:
|
||||||
|
context.lang.switchFrontAndBackCamera,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
cameraState.switchCameraSensor(
|
cameraState.switchCameraSensor(
|
||||||
aspectRatio:
|
aspectRatio:
|
||||||
|
|
@ -185,6 +188,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
// SizedBox(height: 20),
|
// SizedBox(height: 20),
|
||||||
ActionButton(
|
ActionButton(
|
||||||
FontAwesomeIcons.bolt,
|
FontAwesomeIcons.bolt,
|
||||||
|
tooltipText: context.lang.toogleFlashLight,
|
||||||
color: isFlashOn
|
color: isFlashOn
|
||||||
? const Color.fromARGB(255, 255, 230, 0)
|
? const Color.fromARGB(255, 255, 230, 0)
|
||||||
: const Color.fromARGB(
|
: const Color.fromARGB(
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:twonly/src/components/image_editor/action_button.dart';
|
import 'package:twonly/src/components/image_editor/action_button.dart';
|
||||||
import 'package:twonly/src/components/media_view_sizing.dart';
|
import 'package:twonly/src/components/media_view_sizing.dart';
|
||||||
|
import 'package:twonly/src/components/notification_badge.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/views/camera_to_share/share_image_view.dart';
|
import 'package:twonly/src/views/camera_to_share/share_image_view.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
@ -27,6 +27,8 @@ class ShareImageEditorView extends StatefulWidget {
|
||||||
class _ShareImageEditorView extends State<ShareImageEditorView> {
|
class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
bool _imageSaved = false;
|
bool _imageSaved = false;
|
||||||
bool _imageSaving = false;
|
bool _imageSaving = false;
|
||||||
|
bool _isRealTwonly = false;
|
||||||
|
int _maxShowTime = 18;
|
||||||
|
|
||||||
ImageItem currentImage = ImageItem();
|
ImageItem currentImage = ImageItem();
|
||||||
ScreenshotController screenshotController = ScreenshotController();
|
ScreenshotController screenshotController = ScreenshotController();
|
||||||
|
|
@ -51,26 +53,31 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return <Widget>[
|
return <Widget>[
|
||||||
BottomButton(
|
ActionButton(
|
||||||
icon: FontAwesomeIcons.font,
|
FontAwesomeIcons.font,
|
||||||
onTap: () async {
|
tooltipText: context.lang.addTextItem,
|
||||||
|
onPressed: () async {
|
||||||
undoLayers.clear();
|
undoLayers.clear();
|
||||||
removedLayers.clear();
|
removedLayers.clear();
|
||||||
layers.add(TextLayerData());
|
layers.add(TextLayerData());
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
BottomButton(
|
const SizedBox(height: 8),
|
||||||
icon: FontAwesomeIcons.pencil,
|
ActionButton(
|
||||||
onTap: () async {
|
FontAwesomeIcons.pencil,
|
||||||
|
tooltipText: context.lang.addDrawing,
|
||||||
|
onPressed: () async {
|
||||||
undoLayers.clear();
|
undoLayers.clear();
|
||||||
removedLayers.clear();
|
removedLayers.clear();
|
||||||
layers.add(DrawLayerData());
|
layers.add(DrawLayerData());
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
BottomButton(
|
const SizedBox(height: 8),
|
||||||
icon: FontAwesomeIcons.faceGrinWide,
|
ActionButton(
|
||||||
onTap: () async {
|
FontAwesomeIcons.faceGrinWide,
|
||||||
|
tooltipText: context.lang.addEmoji,
|
||||||
|
onPressed: () async {
|
||||||
EmojiLayerData? layer = await showModalBottomSheet(
|
EmojiLayerData? layer = await showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
|
|
@ -78,16 +85,49 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
return const Emojis();
|
return const Emojis();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (layer == null) return;
|
if (layer == null) return;
|
||||||
|
|
||||||
undoLayers.clear();
|
undoLayers.clear();
|
||||||
removedLayers.clear();
|
removedLayers.clear();
|
||||||
layers.add(layer);
|
layers.add(layer);
|
||||||
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
NotificationBadge(
|
||||||
|
count: _maxShowTime == 999999 ? "∞" : _maxShowTime.toString(),
|
||||||
|
// count: "",
|
||||||
|
child: ActionButton(
|
||||||
|
FontAwesomeIcons.stopwatch,
|
||||||
|
tooltipText: context.lang.protectAsARealTwonly,
|
||||||
|
disable: _isRealTwonly,
|
||||||
|
onPressed: () async {
|
||||||
|
if (_maxShowTime == 999999) {
|
||||||
|
_maxShowTime = 4;
|
||||||
|
} else if (_maxShowTime >= 22) {
|
||||||
|
_maxShowTime = 999999;
|
||||||
|
} else {
|
||||||
|
_maxShowTime = _maxShowTime + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _maxShowTime =
|
||||||
|
// _isRealTwonly = !_isRealTwonly;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
ActionButton(
|
||||||
|
FontAwesomeIcons.shieldHeart,
|
||||||
|
tooltipText: context.lang.protectAsARealTwonly,
|
||||||
|
color: _isRealTwonly
|
||||||
|
? Theme.of(context).colorScheme.primary
|
||||||
|
: Colors.white,
|
||||||
|
onPressed: () async {
|
||||||
|
_isRealTwonly = !_isRealTwonly;
|
||||||
|
if (_isRealTwonly) {
|
||||||
|
_maxShowTime = 12;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,6 +140,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
return [
|
return [
|
||||||
ActionButton(
|
ActionButton(
|
||||||
FontAwesomeIcons.xmark,
|
FontAwesomeIcons.xmark,
|
||||||
|
tooltipText: context.lang.close,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
|
|
@ -108,9 +149,8 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
ActionButton(
|
ActionButton(
|
||||||
FontAwesomeIcons.rotateLeft,
|
FontAwesomeIcons.rotateLeft,
|
||||||
color: layers.length > 1 || removedLayers.isNotEmpty
|
tooltipText: context.lang.undo,
|
||||||
? Colors.white
|
disable: layers.length <= 1 && removedLayers.isEmpty,
|
||||||
: Colors.grey,
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (removedLayers.isNotEmpty) {
|
if (removedLayers.isNotEmpty) {
|
||||||
layers.add(removedLayers.removeLast());
|
layers.add(removedLayers.removeLast());
|
||||||
|
|
@ -126,7 +166,8 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
ActionButton(
|
ActionButton(
|
||||||
FontAwesomeIcons.rotateRight,
|
FontAwesomeIcons.rotateRight,
|
||||||
color: undoLayers.isNotEmpty ? Colors.white : Colors.grey,
|
tooltipText: context.lang.redo,
|
||||||
|
disable: undoLayers.isEmpty,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (undoLayers.isEmpty) return;
|
if (undoLayers.isEmpty) return;
|
||||||
layers.add(undoLayers.removeLast());
|
layers.add(undoLayers.removeLast());
|
||||||
|
|
@ -211,7 +252,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
right: 0,
|
right: 6,
|
||||||
top: 100,
|
top: 100,
|
||||||
child: Container(
|
child: Container(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
|
|
@ -266,10 +307,8 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
label: Text(_imageSaved
|
label: Text(_imageSaved
|
||||||
? AppLocalizations.of(context)!
|
? context.lang.shareImagedEditorSavedImage
|
||||||
.shareImagedEditorSavedImage
|
: context.lang.shareImagedEditorSaveImage),
|
||||||
: AppLocalizations.of(context)!
|
|
||||||
.shareImagedEditorSaveImage),
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 20),
|
const SizedBox(width: 20),
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
|
|
@ -280,8 +319,12 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) => ShareImageView(
|
||||||
ShareImageView(imageBytes: imageBytes)),
|
imageBytes: imageBytes,
|
||||||
|
isRealTwonly: _isRealTwonly,
|
||||||
|
maxShowTime: _maxShowTime,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
|
|
@ -290,7 +333,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
label: Text(
|
label: Text(
|
||||||
AppLocalizations.of(context)!.shareImagedEditorShareWith,
|
context.lang.shareImagedEditorShareWith,
|
||||||
style: TextStyle(fontSize: 17),
|
style: TextStyle(fontSize: 17),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -302,57 +345,3 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Button used in bottomNavigationBar in ImageEditor
|
|
||||||
class BottomButton extends StatelessWidget {
|
|
||||||
final VoidCallback? onTap, onLongPress;
|
|
||||||
final IconData icon;
|
|
||||||
final Color color;
|
|
||||||
|
|
||||||
const BottomButton({
|
|
||||||
super.key,
|
|
||||||
this.onTap,
|
|
||||||
this.color = Colors.white,
|
|
||||||
this.onLongPress,
|
|
||||||
required this.icon,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: onTap,
|
|
||||||
onLongPress: onLongPress,
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
ActionButton(
|
|
||||||
icon,
|
|
||||||
color: color,
|
|
||||||
onPressed: onTap ?? () {},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// /// Show image drawing surface over image
|
|
||||||
// class ImageEditorDrawing extends StatefulWidget {
|
|
||||||
// final ImageItem image;
|
|
||||||
|
|
||||||
// const ImageEditorDrawing({
|
|
||||||
// super.key,
|
|
||||||
// required this.image,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// State<ImageEditorDrawing> createState() => _ImageEditorDrawingState();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// class _ImageEditorDrawingState extends State<ImageEditorDrawing> {
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import 'dart:collection';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:fixnum/fixnum.dart';
|
import 'package:fixnum/fixnum.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:twonly/src/components/best_friends_selector.dart';
|
import 'package:twonly/src/components/best_friends_selector.dart';
|
||||||
import 'package:twonly/src/components/flame.dart';
|
import 'package:twonly/src/components/flame.dart';
|
||||||
|
|
@ -14,8 +13,14 @@ import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/views/home_view.dart';
|
import 'package:twonly/src/views/home_view.dart';
|
||||||
|
|
||||||
class ShareImageView extends StatefulWidget {
|
class ShareImageView extends StatefulWidget {
|
||||||
const ShareImageView({super.key, required this.imageBytes});
|
const ShareImageView(
|
||||||
|
{super.key,
|
||||||
|
required this.imageBytes,
|
||||||
|
required this.isRealTwonly,
|
||||||
|
required this.maxShowTime});
|
||||||
final Uint8List imageBytes;
|
final Uint8List imageBytes;
|
||||||
|
final bool isRealTwonly;
|
||||||
|
final int maxShowTime;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ShareImageView> createState() => _ShareImageView();
|
State<ShareImageView> createState() => _ShareImageView();
|
||||||
|
|
@ -92,11 +97,22 @@ class _ShareImageView extends State<ShareImageView> {
|
||||||
_updateUsers(usersFiltered);
|
_updateUsers(usersFiltered);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateStatus(Int64 userId, bool checked) {
|
||||||
|
if (checked) {
|
||||||
|
if (widget.isRealTwonly) {
|
||||||
|
_selectedUserIds.clear();
|
||||||
|
}
|
||||||
|
_selectedUserIds.add(userId);
|
||||||
|
} else {
|
||||||
|
_selectedUserIds.remove(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(AppLocalizations.of(context)!.shareImageTitle),
|
title: Text(context.lang.shareImageTitle),
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10),
|
padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10),
|
||||||
|
|
@ -106,30 +122,24 @@ class _ShareImageView extends State<ShareImageView> {
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
child: TextField(
|
child: TextField(
|
||||||
onChanged: _filterUsers,
|
onChanged: _filterUsers,
|
||||||
decoration: getInputDecoration(context,
|
decoration: getInputDecoration(
|
||||||
AppLocalizations.of(context)!.searchUsernameInput))),
|
context, context.lang.searchUsernameInput))),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
BestFriendsSelector(
|
BestFriendsSelector(
|
||||||
users: _bestFriends,
|
users: _bestFriends,
|
||||||
selectedUserIds: _selectedUserIds,
|
selectedUserIds: _selectedUserIds,
|
||||||
maxTotalMediaCounter: maxTotalMediaCounter,
|
maxTotalMediaCounter: maxTotalMediaCounter,
|
||||||
updateStatus: (userId, checked) {
|
updateStatus: updateStatus,
|
||||||
if (checked) {
|
|
||||||
_selectedUserIds.add(userId);
|
|
||||||
} else {
|
|
||||||
_selectedUserIds.remove(userId);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
if (_otherUsers.isNotEmpty)
|
if (_otherUsers.isNotEmpty)
|
||||||
HeadLineComponent(
|
HeadLineComponent(context.lang.shareImageAllUsers),
|
||||||
AppLocalizations.of(context)!.shareImageAllUsers),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: UserList(
|
child: UserList(
|
||||||
List.from(_otherUsers),
|
List.from(_otherUsers),
|
||||||
maxTotalMediaCounter,
|
maxTotalMediaCounter,
|
||||||
selectedUserIds: _selectedUserIds,
|
selectedUserIds: _selectedUserIds,
|
||||||
|
updateStatus: updateStatus,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
@ -145,7 +155,12 @@ class _ShareImageView extends State<ShareImageView> {
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
icon: FaIcon(FontAwesomeIcons.solidPaperPlane),
|
icon: FaIcon(FontAwesomeIcons.solidPaperPlane),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
sendImage(_selectedUserIds.toList(), widget.imageBytes);
|
sendImage(
|
||||||
|
_selectedUserIds.toList(),
|
||||||
|
widget.imageBytes,
|
||||||
|
widget.isRealTwonly,
|
||||||
|
widget.maxShowTime,
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: pop back to the HomeView page popUntil did not work. check later how to improve in case of pushing more then 2
|
// TODO: pop back to the HomeView page popUntil did not work. check later how to improve in case of pushing more then 2
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
|
|
@ -158,7 +173,7 @@ class _ShareImageView extends State<ShareImageView> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
label: Text(
|
label: Text(
|
||||||
AppLocalizations.of(context)!.shareImagedEditorSendImage,
|
context.lang.shareImagedEditorSendImage,
|
||||||
style: TextStyle(fontSize: 17),
|
style: TextStyle(fontSize: 17),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -172,7 +187,8 @@ class _ShareImageView extends State<ShareImageView> {
|
||||||
|
|
||||||
class UserList extends StatelessWidget {
|
class UserList extends StatelessWidget {
|
||||||
const UserList(this.users, this.maxTotalMediaCounter,
|
const UserList(this.users, this.maxTotalMediaCounter,
|
||||||
{super.key, required this.selectedUserIds});
|
{super.key, required this.selectedUserIds, required this.updateStatus});
|
||||||
|
final Function(Int64, bool) updateStatus;
|
||||||
final List<Contact> users;
|
final List<Contact> users;
|
||||||
final int maxTotalMediaCounter;
|
final int maxTotalMediaCounter;
|
||||||
final HashSet<Int64> selectedUserIds;
|
final HashSet<Int64> selectedUserIds;
|
||||||
|
|
@ -201,19 +217,11 @@ class UserList extends StatelessWidget {
|
||||||
value: selectedUserIds.contains(user.userId),
|
value: selectedUserIds.contains(user.userId),
|
||||||
onChanged: (bool? value) {
|
onChanged: (bool? value) {
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
if (value) {
|
updateStatus(user.userId, value);
|
||||||
selectedUserIds.add(user.userId);
|
|
||||||
} else {
|
|
||||||
selectedUserIds.remove(user.userId);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (!selectedUserIds.contains(user.userId)) {
|
updateStatus(user.userId, !selectedUserIds.contains(user.userId));
|
||||||
selectedUserIds.add(user.userId);
|
|
||||||
} else {
|
|
||||||
selectedUserIds.remove(user.userId);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import 'package:twonly/src/providers/api/api.dart';
|
||||||
import 'package:twonly/src/providers/download_change_provider.dart';
|
import 'package:twonly/src/providers/download_change_provider.dart';
|
||||||
import 'package:twonly/src/providers/messages_change_provider.dart';
|
import 'package:twonly/src/providers/messages_change_provider.dart';
|
||||||
import 'package:twonly/src/views/chats/media_viewer_view.dart';
|
import 'package:twonly/src/views/chats/media_viewer_view.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
class ChatListEntry extends StatelessWidget {
|
class ChatListEntry extends StatelessWidget {
|
||||||
const ChatListEntry(this.message, this.user, this.lastMessageFromSameUser,
|
const ChatListEntry(this.message, this.user, this.lastMessageFromSameUser,
|
||||||
|
|
@ -188,8 +188,7 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
||||||
}
|
}
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(AppLocalizations.of(context)!
|
title: Text(context.lang.chatListDetailTitle(widget.user.displayName)),
|
||||||
.chatListDetailTitle(widget.user.displayName)),
|
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -226,8 +225,7 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
||||||
_sendMessage();
|
_sendMessage();
|
||||||
},
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText:
|
hintText: context.lang.chatListDetailInput,
|
||||||
AppLocalizations.of(context)!.chatListDetailInput,
|
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10)
|
contentPadding: EdgeInsets.symmetric(horizontal: 10)
|
||||||
// border: OutlineInputBorder(),
|
// border: OutlineInputBorder(),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import 'package:twonly/src/views/home_view.dart';
|
||||||
import 'package:twonly/src/views/chats/media_viewer_view.dart';
|
import 'package:twonly/src/views/chats/media_viewer_view.dart';
|
||||||
import 'package:twonly/src/views/profile_view.dart';
|
import 'package:twonly/src/views/profile_view.dart';
|
||||||
import 'package:twonly/src/views/chats/search_username_view.dart';
|
import 'package:twonly/src/views/chats/search_username_view.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ChatItem {
|
class ChatItem {
|
||||||
|
|
@ -86,7 +85,10 @@ class _ChatListViewState extends State<ChatListView> {
|
||||||
// title:
|
// title:
|
||||||
actions: [
|
actions: [
|
||||||
NotificationBadge(
|
NotificationBadge(
|
||||||
count: context.watch<ContactChangeProvider>().newContactRequests,
|
count: context
|
||||||
|
.watch<ContactChangeProvider>()
|
||||||
|
.newContactRequests
|
||||||
|
.toString(),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: FaIcon(FontAwesomeIcons.userPlus, size: 18),
|
icon: FaIcon(FontAwesomeIcons.userPlus, size: 18),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
@ -131,10 +133,8 @@ class _ChatListViewState extends State<ChatListView> {
|
||||||
: globalUpdateOfHomeViewPageIndex(1);
|
: globalUpdateOfHomeViewPageIndex(1);
|
||||||
},
|
},
|
||||||
label: Text((activeUsers.isEmpty)
|
label: Text((activeUsers.isEmpty)
|
||||||
? AppLocalizations.of(context)!
|
? context.lang.chatListViewSearchUserNameBtn
|
||||||
.chatListViewSearchUserNameBtn
|
: context.lang.chatListViewSendFirstTwonly)),
|
||||||
: AppLocalizations.of(context)!
|
|
||||||
.chatListViewSendFirstTwonly)),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: ListView.builder(
|
: ListView.builder(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:twonly/main.dart';
|
import 'package:twonly/main.dart';
|
||||||
import 'package:twonly/src/components/headline.dart';
|
import 'package:twonly/src/components/headline.dart';
|
||||||
|
|
@ -77,7 +77,7 @@ class _SearchUsernameView extends State<SearchUsernameView> {
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(AppLocalizations.of(context)!.searchUsernameTitle),
|
title: Text(context.lang.searchUsernameTitle),
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10),
|
padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10),
|
||||||
|
|
@ -90,8 +90,8 @@ class _SearchUsernameView extends State<SearchUsernameView> {
|
||||||
_addNewUser(context);
|
_addNewUser(context);
|
||||||
},
|
},
|
||||||
controller: searchUserName,
|
controller: searchUserName,
|
||||||
decoration: getInputDecoration(
|
decoration:
|
||||||
AppLocalizations.of(context)!.searchUsernameInput),
|
getInputDecoration(context.lang.searchUsernameInput),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
@ -101,8 +101,7 @@ class _SearchUsernameView extends State<SearchUsernameView> {
|
||||||
showAlertDialog(context, "Coming soon",
|
showAlertDialog(context, "Coming soon",
|
||||||
"This feature is not yet implemented!");
|
"This feature is not yet implemented!");
|
||||||
},
|
},
|
||||||
label:
|
label: Text(context.lang.searchUsernameQrCodeBtn),
|
||||||
Text(AppLocalizations.of(context)!.searchUsernameQrCodeBtn),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 30),
|
SizedBox(height: 30),
|
||||||
if (context
|
if (context
|
||||||
|
|
@ -110,8 +109,7 @@ class _SearchUsernameView extends State<SearchUsernameView> {
|
||||||
.allContacts
|
.allContacts
|
||||||
.where((contact) => !contact.accepted)
|
.where((contact) => !contact.accepted)
|
||||||
.isNotEmpty)
|
.isNotEmpty)
|
||||||
HeadLineComponent(
|
HeadLineComponent(context.lang.searchUsernameNewFollowerTitle),
|
||||||
AppLocalizations.of(context)!.searchUsernameNewFollowerTitle),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ContactsListView(),
|
child: ContactsListView(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import 'package:logging/logging.dart';
|
||||||
import 'package:twonly/main.dart';
|
import 'package:twonly/main.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
||||||
import 'package:twonly/src/model/json/user_data.dart';
|
import 'package:twonly/src/model/json/user_data.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/utils/signal.dart';
|
import 'package:twonly/src/utils/signal.dart';
|
||||||
|
|
@ -75,14 +74,14 @@ class _RegisterViewState extends State<RegisterView> {
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 50),
|
const SizedBox(height: 50),
|
||||||
Text(
|
Text(
|
||||||
AppLocalizations.of(context)!.registerTitle,
|
context.lang.registerTitle,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 30),
|
style: TextStyle(fontSize: 30),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 30),
|
padding: EdgeInsets.symmetric(horizontal: 30),
|
||||||
child: Text(
|
child: Text(
|
||||||
AppLocalizations.of(context)!.registerSlogan,
|
context.lang.registerSlogan,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 12),
|
style: TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
|
|
@ -92,7 +91,7 @@ class _RegisterViewState extends State<RegisterView> {
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(left: 10, right: 10),
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
AppLocalizations.of(context)!.registerUsernameSlogan,
|
context.lang.registerUsernameSlogan,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 15),
|
style: TextStyle(fontSize: 15),
|
||||||
),
|
),
|
||||||
|
|
@ -107,7 +106,7 @@ class _RegisterViewState extends State<RegisterView> {
|
||||||
],
|
],
|
||||||
style: TextStyle(fontSize: 17),
|
style: TextStyle(fontSize: 17),
|
||||||
decoration: getInputDecoration(
|
decoration: getInputDecoration(
|
||||||
AppLocalizations.of(context)!.registerUsernameDecoration,
|
context.lang.registerUsernameDecoration,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
|
|
@ -115,7 +114,7 @@ class _RegisterViewState extends State<RegisterView> {
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(left: 10, right: 10),
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
AppLocalizations.of(context)!.registerUsernameLimits,
|
context.lang.registerUsernameLimits,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 7),
|
style: TextStyle(fontSize: 7),
|
||||||
),
|
),
|
||||||
|
|
@ -166,7 +165,7 @@ class _RegisterViewState extends State<RegisterView> {
|
||||||
Colors.grey)
|
Colors.grey)
|
||||||
: null),
|
: null),
|
||||||
label: Text(
|
label: Text(
|
||||||
AppLocalizations.of(context)!.registerSubmitButton,
|
context.lang.registerSubmitButton,
|
||||||
style: TextStyle(fontSize: 17),
|
style: TextStyle(fontSize: 17),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue