Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v0.9.2 #2148

Merged
merged 51 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
2ad05c1
TF-1845 Fix the searching result is not correct with the condition `D…
dab246 Aug 24, 2023
306dc8f
TF-1844 Automatically perform search action after user fills in input…
dab246 Aug 23, 2023
e8c61b0
TF-1844 Highlight autocomplete suggestion item when hovering in advan…
dab246 Aug 23, 2023
e103939
TF-1844 Update hint text input advanced search
dab246 Aug 23, 2023
26552a5
TF-1844 Fix mailbox not selected in advanced search
dab246 Aug 23, 2023
dd20b39
tf-1946 add swipe to thread
hieutbui Aug 28, 2023
c225cf8
Disable swipe right-to-left on thread
hieutbui Aug 29, 2023
d95ff35
TF-1977 Redirect to Inbox when clicking on logo
dab246 Aug 29, 2023
5165e50
TF-1977 Disable highlight color when clicking logo
dab246 Aug 29, 2023
50c1486
TF-1977 Rename the method for clarity
dab246 Aug 29, 2023
7ded22f
TF-1977 Close email view and scroll to position inbox when clicking o…
dab246 Aug 29, 2023
7fe338a
Fix the login screen freezes when pasting the link in the browser add…
dab246 Aug 28, 2023
f34c126
Fix TextEditingController was used after being disposed in LoginView
dab246 Aug 28, 2023
1f840ed
Make the beautify logging tool
dab246 Aug 28, 2023
80c1eac
Replace all `png` icon to `svg` icon
dab246 Aug 28, 2023
91cfb8f
Remove NoAuthenticatedAccountFailure state unnecessary
dab246 Aug 29, 2023
fe2721c
Check OIDC available when no account is logged in
dab246 Aug 29, 2023
a17703c
Convert LoginTextInputBuilder functional to StatefulWidget
dab246 Aug 30, 2023
dbb1c0b
TF-1984 Show `Empty` action for Trash and Spam mailbox
dab246 Aug 30, 2023
f84a2e4
TF-1984 Show popup dialog when clicking on Empty button
dab246 Aug 30, 2023
5bc745f
TF-1984 Move `Get.find()` outside the build method
dab246 Aug 30, 2023
56107f6
TF-1984 Update logger by standard format
dab246 Aug 30, 2023
75bf607
TF-1984 Handle empty Trash and Spam mailbox action
dab246 Aug 30, 2023
51e3a3d
TF-2026 Add `SaveToDraftAndClose` method
dab246 Aug 30, 2023
1412171
TF-2026 Implement `SaveToDraft` method
dab246 Aug 30, 2023
a7f5225
TF-2129 Fix cannot attach file on mobile
dab246 Sep 7, 2023
1b8bd62
TF-2129 Fix print log on mobile
dab246 Sep 7, 2023
d8eeb20
TF-2129 Show full attachment for the first time
dab246 Sep 7, 2023
e0b8eaf
Handle call retry up to 3 time when `statusCode=401`
dab246 Sep 8, 2023
6444606
Add `adr` to fix oidc refresh token using `QueuedInterceptor`
dab246 Sep 11, 2023
ab753d8
TF-2083 add RuleFilterConditionWidget
hieutbui Aug 30, 2023
effc1ea
TF-2083 change condition widget to RuleFilterConditionWidget
hieutbui Aug 31, 2023
e4cf5be
TF-2083 Add listRuleCondition
hieutbui Aug 31, 2023
bc64743
tf-2083 make each rule condition can change value field separately
hieutbui Sep 6, 2023
5e00aea
tf-2083 add swipe to remove condition on mobile
hieutbui Sep 6, 2023
6f24812
TF-2083 Change input field arguments
hieutbui Sep 8, 2023
083e376
TF-2083 Add condition row widget and condition remove button widget
hieutbui Sep 11, 2023
7a598a2
TF-2089 Add `dash-dash-space` to signature delimiter
dab246 Sep 11, 2023
a1a6148
Change license to AGPL-V3 - drop the OpenPaaS clause
chibenwa Sep 12, 2023
d78bab1
Add badges for downloads (#2140)
chibenwa Sep 13, 2023
94f30fb
TF-2134 Remove the leading hash(#) from the URL of web
dab246 Sep 11, 2023
7f12319
TF-2134 Add MailtoURLView page
dab246 Sep 11, 2023
051f7f6
TF-2134 Add mailto page router
dab246 Sep 11, 2023
3022fc9
TF-2134 Handle navigation route from mailto URL
dab246 Sep 11, 2023
46999c2
TF-2134 Open composer from mailto uri
dab246 Sep 11, 2023
3d60b84
TF-2135 Add splash screen for web
dab246 Sep 13, 2023
60f77e0
Translated using Weblate (German)
Atalanttore Sep 3, 2023
d34e3a8
Translated using Weblate (Russian)
tprudentova Sep 6, 2023
0602c56
Translated using Weblate (French)
chibenwa Sep 12, 2023
129d17c
Hotfix: Temporarily hide `Add condition` in filter rule for release n…
dab246 Sep 14, 2023
4cc6af2
Bump version to `v0.9.2`
dab246 Sep 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
## [0.9.2] - 2023-09-14
### Changed
- \#2134 \[WEB\] mailto URL
- Translate Russian/French/German
- \#2124 Add badges for downloads (#2140)
- \#2123 Change license to AGPL-V3 - drop the OpenPaaS clause

### Fixed
- \#1844 Fix \[AdvanceSearch\] User cannot get the advance searching result once user use Enter without the clicking Search button
- \#1845 Fix \[AdvanceSearch\] The searching result is not correct with the condition which mention in the description
- \#1977 Fix clickable logo
- \#1984 Fix \[Barcamp\] Counter for Trash/Spam + empty action for Trash/Spam
- \#2026 Fix \[COMPOSER\] Save as draft should not close the composer
- \#2129 Fix \[Attach image\] I cannot attach image
- \#2135 Add Splash Screen for user to prevent blank page in the first time loading TeamMail app
- \#2089 Add dash-dash-space to signature delimiter
- Fix the login screen freezes when pasting the link in the browser address bar
- Fix TextEditingController was used after being disposed in LoginView
- Fix oidc refresh token on mobile

## [0.9.1] - 2023-08-23
### Fixed
- \#1974 Fix refreshToken with OIDC on jmap.linagora.com/oidc
Expand Down Expand Up @@ -237,6 +257,7 @@
- \#1512 remove plain text input for signature
- \#1469 remove animation when navigating screen

[0.9.2]: https://github.com/linagora/tmail-flutter/releases/tag/v0.9.2
[0.9.1]: https://github.com/linagora/tmail-flutter/releases/tag/v0.9.1
[0.9.0]: https://github.com/linagora/tmail-flutter/releases/tag/v0.9.0
[0.8.9]: https://github.com/linagora/tmail-flutter/releases/tag/v0.8.9
Expand Down
1,193 changes: 593 additions & 600 deletions LICENSE

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Team Mail Flutter mobile application

[![Gitter](https://badges.gitter.im/linagora/team-mail.svg)](https://gitter.im/linagora/team-mail?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Documentation](https://img.shields.io/badge/Documentation-green.svg)](docs)
[![Images docker](https://img.shields.io/badge/Images-docker-blue.svg)](https://hub.docker.com/r/linagora/tmail-web)
[![Android application](https://img.shields.io/badge/App-Android-blue.svg)](https://play.google.com/store/apps/details?id=com.linagora.android.teammail)
[![Ios application](https://img.shields.io/badge/App-Ios-blue.svg)](https://apps.apple.com/gr/app/teammail/id1587086189)

![LOGO](https://user-images.githubusercontent.com/6462404/202656316-8b77a7b6-0c1f-4f3e-932b-72bd446b6605.png)


This project aims at providing a multi-platform mobile email application, running the [JMAP protocol](https://jmap.io/) and will also deliver additional
features to the [Team Mail back-end](https://github.com/linagora/tmail-backend).

Expand Down
Binary file added assets/icons/icon_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/images/2.0x/login_graphic.png
Binary file not shown.
Binary file removed assets/images/2.0x/logo_tmail.png
Binary file not shown.
Binary file removed assets/images/3.0x/login_graphic.png
Binary file not shown.
Binary file removed assets/images/3.0x/logo_tmail.png
Binary file not shown.
823 changes: 823 additions & 0 deletions assets/images/ic_login_graphic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions assets/images/ic_tmail_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/images/login_graphic.png
Binary file not shown.
Binary file removed assets/images/logo_tmail.png
Binary file not shown.
1 change: 1 addition & 0 deletions core/lib/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export 'presentation/views/toast/tmail_toast.dart';
export 'presentation/views/bottom_popup/full_screen_action_sheet_builder.dart';
export 'presentation/views/checkbox/labeled_checkbox.dart';
export 'presentation/views/container/tmail_container_widget.dart';
export 'presentation/views/clipper/side_arrow_clipper.dart';

// Resources
export 'presentation/resources/assets_paths.dart';
Expand Down
5 changes: 5 additions & 0 deletions core/lib/presentation/extensions/color_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ extension AppColor on Color {
static const colorLabelQuotas = Color(0xFF818C99);
static const colorLabelCancelButton = Color(0xFFAEB7C2);
static const colorCreateFiltersButton = Color(0xFFF3F3F7);
static const colorTextBody = Color(0xFF818C99);
static const colorClosePopupDialogButton = Color(0xFFAEB7C2);
static const colorEmptyPopupDialogButton = Color(0xFFFFC107);
static const colorCancelPopupDialogButton = Color(0xFFEBEDF0);
static const colorRemoveRuleFilterConditionButton = Color(0xFFE6E8EC);

static const mapGradientColor = [
[Color(0xFF21D4FD), Color(0xFFB721FF)],
Expand Down
2 changes: 1 addition & 1 deletion core/lib/presentation/extensions/html_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
extension HtmlExtension on String {

static const String editorStartTags = '<br><div><br></div>';
static const String signaturePrefix = '-- ';
static const String signaturePrefix = '--&nbsp;';

String addBlockTag(String tag, {String? attribute}) =>
attribute != null
Expand Down
4 changes: 2 additions & 2 deletions core/lib/presentation/resources/image_paths.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ class ImagePaths {
String get icFilterSelected => _getImagePath('ic_filter_selected.svg');
String get icFilterMessageAll => _getImagePath('ic_filter_message_all.svg');
String get icFilterMessageAttachments => _getImagePath('ic_filter_message_attachments.svg');
String get icLogoTMail => _getImagePath('logo_tmail.png');
String get icSendToast => _getImagePath('ic_send_toast.svg');
String get icSendSuccessToast => _getImagePath('ic_send_success_toast.svg');
String get icClearTextSearch => _getImagePath('ic_clear_text_search.svg');
Expand Down Expand Up @@ -97,7 +96,6 @@ class ImagePaths {
String get icEncrypted => _getImagePath('ic_encrypted.svg');
String get icIntegration => _getImagePath('ic_integration.svg');
String get icTeam => _getImagePath('ic_team.svg');
String get loginGraphic => _getImagePath('login_graphic.png');
String get icPowerByLinagora => _getImagePath('power_by_linagora.svg');
String get icAttachmentSB => _getImagePath('ic_attachment_sb.svg');
String get icCalendarSB => _getImagePath('ic_calendar_sb.svg');
Expand Down Expand Up @@ -199,6 +197,8 @@ class ImagePaths {
String get icEventUpdated => _getImagePath('ic_event_updated.svg');
String get icEventCanceled => _getImagePath('ic_event_canceled.svg');
String get icFormatQuote => _getImagePath('ic_format_quote.svg');
String get icTMailLogo => _getImagePath('ic_tmail_logo.svg');
String get icLoginGraphic => _getImagePath('ic_login_graphic.svg');

String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
Expand Down
54 changes: 54 additions & 0 deletions core/lib/presentation/views/clipper/side_arrow_clipper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';

/// Create a custom clipper with a side arrow.
/// To help achieve various custom shapes of widget
class SideArrowClipper extends CustomClipper<Path> {
/// Alignment
final bool isRight;

///The radius, which creates the curved appearance of the widget has a default value of 16.
final double radius;

/// The arrow creates the curved shape of the widget and has a default arrowSize of 8.
final double arrowSize;

/// Offset show distance from bottom and has default value 30.
final double offset;

SideArrowClipper({
this.isRight = false,
this.radius = 16,
this.offset = 30,
this.arrowSize = 8
});

@override
Path getClip(Size size) {
var path = Path();

if (isRight) {
path.addRRect(RRect.fromLTRBR(0, 0, size.width - arrowSize, size.height, Radius.circular(radius)));

var path2 = Path();
path2.lineTo(arrowSize, arrowSize);
path2.lineTo(0, 2 * arrowSize);
path2.lineTo(0, 0);

path.addPath(path2, Offset(size.width - arrowSize, size.height - offset - 2 * arrowSize));
} else {
path.addRRect(RRect.fromLTRBR(arrowSize, 0, size.width, size.height, Radius.circular(radius)));

var path2 = Path();
path2.lineTo(0, 2 * arrowSize);
path2.lineTo(-arrowSize, arrowSize);
path2.lineTo(0, 0);

path.addPath(path2, Offset(arrowSize, size.height - offset - 2 * arrowSize));
}

return path;
}

@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
84 changes: 39 additions & 45 deletions core/lib/presentation/views/text/slogan_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,56 +44,50 @@ class SloganBuilder extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (!arrangedByHorizontal) {
return Material(
color: Colors.transparent,
child: InkWell(
onTap: onTapCallback,
hoverColor: hoverColor,
borderRadius: BorderRadius.all(Radius.circular(hoverRadius ?? 8)),
child: Padding(
padding: padding ?? EdgeInsets.zero,
child: Column(children: [
_logoApp(),
Padding(
padding: paddingText ?? const EdgeInsetsDirectional.only(top: 16, start: 16, end: 16),
child: Text(
text ?? '',
style: textStyle,
textAlign: textAlign,
overflow: enableOverflow ? CommonTextStyle.defaultTextOverFlow : null,
softWrap: enableOverflow ? CommonTextStyle.defaultSoftWrap : null,
maxLines: enableOverflow ? 1 : null,
),
return InkWell(
onTap: onTapCallback,
hoverColor: hoverColor,
borderRadius: BorderRadius.all(Radius.circular(hoverRadius ?? 8)),
child: Padding(
padding: padding ?? EdgeInsets.zero,
child: Column(children: [
_logoApp(),
Padding(
padding: paddingText ?? const EdgeInsetsDirectional.only(top: 16, start: 16, end: 16),
child: Text(
text ?? '',
style: textStyle,
textAlign: textAlign,
overflow: enableOverflow ? CommonTextStyle.defaultTextOverFlow : null,
softWrap: enableOverflow ? CommonTextStyle.defaultSoftWrap : null,
maxLines: enableOverflow ? 1 : null,
),
]),
),
),
]),
),
);
} else {
return Material(
color: Colors.transparent,
child: InkWell(
onTap: onTapCallback,
hoverColor: hoverColor,
radius: hoverRadius ?? 8,
borderRadius: BorderRadius.all(Radius.circular(hoverRadius ?? 8)),
child: Padding(
padding: padding ?? EdgeInsets.zero,
child: Row(children: [
_logoApp(),
Padding(
padding: paddingText ?? const EdgeInsets.symmetric(horizontal: 10),
child: Text(
text ?? '',
style: textStyle,
textAlign: textAlign,
overflow: enableOverflow ? CommonTextStyle.defaultTextOverFlow : null,
softWrap: enableOverflow ? CommonTextStyle.defaultSoftWrap : null,
maxLines: enableOverflow ? 1 : null,
),
return InkWell(
onTap: onTapCallback,
hoverColor: hoverColor,
radius: hoverRadius ?? 8,
borderRadius: BorderRadius.all(Radius.circular(hoverRadius ?? 8)),
child: Padding(
padding: padding ?? EdgeInsets.zero,
child: Row(children: [
_logoApp(),
Padding(
padding: paddingText ?? const EdgeInsets.symmetric(horizontal: 10),
child: Text(
text ?? '',
style: textStyle,
textAlign: textAlign,
overflow: enableOverflow ? CommonTextStyle.defaultTextOverFlow : null,
softWrap: enableOverflow ? CommonTextStyle.defaultSoftWrap : null,
maxLines: enableOverflow ? 1 : null,
),
]),
),
),
]),
),
);
}
Expand Down
64 changes: 53 additions & 11 deletions core/lib/utils/app_logger.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,76 @@
import 'dart:async';

import 'package:core/utils/platform_info.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

final logHistory = _Dispatcher("");
final logHistory = _Dispatcher('');

void log(String? value) {
if (kDebugMode) {
String v = value ?? "";
logHistory.value = "$v\n${logHistory.value}";
print(v);
void log(String? value, {Level level = Level.info}) {
if (!kDebugMode) return;

String logsStr = value ?? '';
logHistory.value = '$logsStr\n${logHistory.value}';

if (PlatformInfo.isWeb) {
switch (level) {
case Level.wtf:
logsStr = '\x1B[31m!!!CRITICAL!!! $logsStr\x1B[0m';
break;
case Level.error:
logsStr = '\x1B[31m$logsStr\x1B[0m';
break;
case Level.warning:
logsStr = '\x1B[33m$logsStr\x1B[0m';
break;
case Level.info:
logsStr = '\x1B[32m$logsStr\x1B[0m';
break;
case Level.debug:
logsStr = '\x1B[34m$logsStr\x1B[0m';
break;
case Level.verbose:
break;
}
} else {
switch (level) {
case Level.error:
logsStr = '[ERROR] $logsStr';
break;
default:
break;
}
}
// ignore: avoid_print
print('[TeamMail] $logsStr');
}

void logError(String? value) => log("[ERROR] ${value ?? ""}");
void logError(String? value) => log(value, level: Level.error);

// Take from: https://flutter.dev/docs/testing/errors
void initLogger(VoidCallback runApp) {
runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.onError = (details) {
FlutterError.dumpErrorToConsole(details);
logError(details.stack.toString());
logError('AppLogger::initLogger::runZonedGuarded:FlutterError.onError: ${details.stack.toString()}');
};
runApp.call();
}, (Object error, StackTrace stack) {
logError(stack.toString());
}, (error, stack) {
logError('AppLogger::initLogger::runZonedGuarded:onError: $error | stack: $stack');
});
}

class _Dispatcher extends ValueNotifier<String> {
_Dispatcher(String value) : super(value);
}


enum Level {
wtf,
error,
warning,
info,
debug,
verbose,
}
Loading
Loading