TF-1194 apply new design identity to manage identity screen in mobile
This commit is contained in:
+79
@@ -0,0 +1,79 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identities_controller.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/widgets/signature_of_identity_builder.dart';
|
||||
|
||||
import 'identity_list_tile_builder.dart';
|
||||
|
||||
class IdentitiesRadioListBuilder extends StatefulWidget {
|
||||
const IdentitiesRadioListBuilder({
|
||||
Key? key,
|
||||
required this.controller,
|
||||
}) : super(key: key);
|
||||
|
||||
final IdentitiesController controller;
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _IdentitiesRadioListBuilderState();
|
||||
}
|
||||
|
||||
class _IdentitiesRadioListBuilderState extends State<IdentitiesRadioListBuilder> {
|
||||
late final controller = widget.controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (controller.listAllIdentities.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Container(
|
||||
foregroundDecoration: BoxDecoration(
|
||||
border: Border.all(color: AppColor.colorBorderIdentityInfo, width: 1),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
|
||||
),
|
||||
child: Obx(() => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
key: const Key('identities_checkbox_list'),
|
||||
height: 256,
|
||||
foregroundDecoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [0, 0.5, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 1].map((e)
|
||||
=> Colors.white.withOpacity(e.toDouble())).toList(),
|
||||
stops: const [0.8, 0.82, 0.84, 0.86, 0.88, 0.90, 0.92, 0.94, 0.96, 0.98, 1],// Gradient from https://learnui.design/tools/gradient-generator.html
|
||||
tileMode: TileMode.mirror,
|
||||
),
|
||||
border: controller.isSignatureShow() ? const Border(bottom: BorderSide(color: AppColor.colorBorderIdentityInfo)): null,
|
||||
),
|
||||
padding: const EdgeInsets.only(left: 12.0, bottom: 12.0, top: 12.0, right: 4.0),
|
||||
child: Scrollbar(
|
||||
child: MediaQuery.removePadding(
|
||||
context: context,
|
||||
removeTop: true,
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.only(right: 12.0),
|
||||
itemCount: controller.listAllIdentities.value.length,
|
||||
itemBuilder: ((context, index) {
|
||||
return IdentityListTileBuilder(
|
||||
controller: widget.controller,
|
||||
index: index,
|
||||
selected: widget.controller.selectedIndex.value,
|
||||
);
|
||||
}),
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
if(controller.isSignatureShow())
|
||||
Obx(() => SignatureOfIdentityBuilder(identity: controller.identitySelected.value!)),
|
||||
],
|
||||
),
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:jmap_dart_client/jmap/identities/identity.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identities_controller.dart';
|
||||
|
||||
class IdentityListTileBuilder extends StatelessWidget {
|
||||
const IdentityListTileBuilder({
|
||||
Key? key,
|
||||
required this.controller,
|
||||
required this.index,
|
||||
required this.selected
|
||||
}) : super(key: key);
|
||||
|
||||
final IdentitiesController controller;
|
||||
final int index;
|
||||
final int? selected;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final imagePaths = controller.imagePaths;
|
||||
final listAllIdentities = controller.listAllIdentities.value;
|
||||
final identity = listAllIdentities[index];
|
||||
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
onTap: () => controller.selectIdentity(index),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
color: isIdentitySelected(index) ? AppColor.colorItemSelected : Colors.transparent,
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 12.0, bottom: 12.0, right: 12.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: BuildUtils.isWeb ? 8.0 : 0.0),
|
||||
child: Radio<int>(
|
||||
value: index,
|
||||
groupValue: selected,
|
||||
onChanged: (selectedValue) => controller.selectIdentity(index),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
identity.name ?? '',
|
||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 16,
|
||||
color: Colors.black)),
|
||||
_buildIconWithTextLine(imagePaths.icEmail, identity.email),
|
||||
for(final widget in _buildReplyLines(identity, imagePaths))
|
||||
widget
|
||||
],
|
||||
)
|
||||
),
|
||||
if(isIdentitySelected(index))...[
|
||||
buildSVGIconButton(
|
||||
padding: const EdgeInsets.only(left: 12.0, right: 12.0),
|
||||
icon: imagePaths.icEdit,
|
||||
iconSize: 24,
|
||||
iconColor: AppColor.primaryColor,
|
||||
onTap: () => controller.goToEditIdentity(context, controller.identitySelected.value!),
|
||||
),
|
||||
buildSVGIconButton(
|
||||
padding: const EdgeInsets.only(right: 0.0),
|
||||
icon: imagePaths.icDeleteOutline,
|
||||
iconSize: 24,
|
||||
iconColor: AppColor.colorActionDeleteConfirmDialog,
|
||||
onTap: () => controller.openConfirmationDialogDeleteIdentityAction(context, controller.identitySelected.value!),
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildReplyLines(Identity? identity, ImagePaths imagePaths) {
|
||||
return [
|
||||
for(var identityReplyTo in identity?.replyTo?.toList() ?? [])
|
||||
_buildIconWithTextLine(imagePaths.icReply, identityReplyTo.email)];
|
||||
}
|
||||
|
||||
Widget _buildIconWithTextLine(String imagePath, String? text) {
|
||||
return Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: SvgPicture.asset(
|
||||
imagePath,
|
||||
color: AppColor.primaryColor,
|
||||
width: 16,
|
||||
fit: BoxFit.fitHeight,
|
||||
)),
|
||||
// replacement character after ..., so wrap it inside richtext is workaround solution
|
||||
Expanded(child: Text(
|
||||
text ?? '', style: const TextStyle(
|
||||
color: AppColor.colorEmailAddressFull,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 13,
|
||||
),
|
||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||
)),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
bool isIdentitySelected(int index) {
|
||||
return index == selected;
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:html_unescape/html_unescape_small.dart';
|
||||
import 'package:jmap_dart_client/jmap/identities/identity.dart';
|
||||
|
||||
class SignatureBuilder extends StatelessWidget {
|
||||
SignatureBuilder({
|
||||
Key? key,
|
||||
this.width,
|
||||
this.height,
|
||||
this.htmlSignature,
|
||||
this.textSignature,
|
||||
}) : super(key: key);
|
||||
|
||||
final Signature? htmlSignature;
|
||||
final Signature? textSignature;
|
||||
final double? width;
|
||||
final double? height;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final signatureWidth = width ?? constraints.biggest.width;
|
||||
final signatureHeight = height ?? constraints.biggest.height;
|
||||
return Container(
|
||||
width: signatureWidth,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 16.0),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
),
|
||||
child: _buildSignature(signatureWidth, signatureHeight),
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSignature(double width, double height) {
|
||||
Widget signature;
|
||||
if (htmlSignature != null && htmlSignature!.value.isNotEmpty) {
|
||||
final htmlSignatureDecoded = _decodeHtml(htmlSignature!.value);
|
||||
if (BuildUtils.isWeb) {
|
||||
signature = HtmlContentViewerOnWeb(
|
||||
contentHtml: htmlSignatureDecoded,
|
||||
widthContent: width,
|
||||
heightContent: height,
|
||||
controller: HtmlViewerControllerForWeb(),
|
||||
allowResizeToDocumentSize: false);
|
||||
} else {
|
||||
signature = HtmlContentViewer(contentHtml: htmlSignatureDecoded, heightContent: height);
|
||||
}
|
||||
} else if (textSignature != null) {
|
||||
signature = Text(textSignature!.value);
|
||||
} else {
|
||||
signature = SizedBox.fromSize(size: Size(width, height));
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
String _decodeHtml(String htmlString) {
|
||||
final unescape = HtmlUnescape();
|
||||
return unescape.convert(htmlString);
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:jmap_dart_client/jmap/identities/identity.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/widgets/signature_builder.dart';
|
||||
|
||||
class SignatureOfIdentityBuilder extends StatelessWidget {
|
||||
|
||||
SignatureOfIdentityBuilder({required this.identity});
|
||||
|
||||
final Identity identity;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SignatureBuilder(
|
||||
height: 256,
|
||||
htmlSignature: identity.htmlSignature,
|
||||
textSignature: identity.textSignature
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user