|
|
|
@ -146,133 +146,129 @@ class FileBubbleState extends State<FileBubble> {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return LayoutBuilder(builder: (bcontext, constraints) {
|
|
|
|
|
var wdgSender = Visibility(
|
|
|
|
|
visible: widget.interactive,
|
|
|
|
|
child: Container(
|
|
|
|
|
height: 14 * Provider.of<Settings>(context).fontScaling,
|
|
|
|
|
clipBehavior: Clip.hardEdge,
|
|
|
|
|
decoration: BoxDecoration(),
|
|
|
|
|
child: compileSenderWidget(context, constraints, fromMe, senderDisplayStr)));
|
|
|
|
|
var isPreview = false;
|
|
|
|
|
var wdgMessage = !showFileSharing
|
|
|
|
|
? Text(AppLocalizations.of(context)!.messageEnableFileSharing, style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle))
|
|
|
|
|
: fromMe
|
|
|
|
|
? senderFileChrome(AppLocalizations.of(context)!.messageFileSent, widget.nameSuggestion, widget.rootHash, widget.fileSize)
|
|
|
|
|
: (fileChrome(AppLocalizations.of(context)!.messageFileOffered + ":", widget.nameSuggestion, widget.rootHash, widget.fileSize,
|
|
|
|
|
Provider.of<ProfileInfoState>(context).downloadSpeed(widget.fileKey())));
|
|
|
|
|
Widget wdgDecorations;
|
|
|
|
|
var wdgSender = Visibility(
|
|
|
|
|
visible: widget.interactive,
|
|
|
|
|
child: Container(
|
|
|
|
|
height: 14 * Provider.of<Settings>(context).fontScaling, clipBehavior: Clip.hardEdge, decoration: BoxDecoration(), child: compileSenderWidget(context, null, fromMe, senderDisplayStr)));
|
|
|
|
|
var isPreview = false;
|
|
|
|
|
var wdgMessage = !showFileSharing
|
|
|
|
|
? Text(AppLocalizations.of(context)!.messageEnableFileSharing, style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle))
|
|
|
|
|
: fromMe
|
|
|
|
|
? senderFileChrome(AppLocalizations.of(context)!.messageFileSent, widget.nameSuggestion, widget.rootHash)
|
|
|
|
|
: (fileChrome(AppLocalizations.of(context)!.messageFileOffered + ":", widget.nameSuggestion, widget.rootHash, widget.fileSize,
|
|
|
|
|
Provider.of<ProfileInfoState>(context).downloadSpeed(widget.fileKey())));
|
|
|
|
|
Widget wdgDecorations;
|
|
|
|
|
|
|
|
|
|
if (!showFileSharing) {
|
|
|
|
|
wdgDecorations = Text('\u202F');
|
|
|
|
|
} else if (downloadComplete && path != null) {
|
|
|
|
|
// in this case, whatever marked download.complete would have also set the path
|
|
|
|
|
if (myFile != null && Provider.of<Settings>(context).shouldPreview(path)) {
|
|
|
|
|
isPreview = true;
|
|
|
|
|
wdgDecorations = Center(
|
|
|
|
|
widthFactor: 1.0,
|
|
|
|
|
child: MouseRegion(
|
|
|
|
|
cursor: SystemMouseCursors.click,
|
|
|
|
|
child: GestureDetector(
|
|
|
|
|
child: Padding(padding: EdgeInsets.all(1.0), child: getPreview(context)),
|
|
|
|
|
onTap: () {
|
|
|
|
|
pop(bcontext, myFile!, widget.nameSuggestion);
|
|
|
|
|
},
|
|
|
|
|
)));
|
|
|
|
|
} else {
|
|
|
|
|
wdgDecorations = Visibility(
|
|
|
|
|
visible: widget.interactive, child: Text(AppLocalizations.of(context)!.fileSavedTo + ': ' + path + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle)));
|
|
|
|
|
}
|
|
|
|
|
} else if (downloadActive) {
|
|
|
|
|
if (!downloadGotManifest) {
|
|
|
|
|
wdgDecorations = Visibility(
|
|
|
|
|
visible: widget.interactive, child: Text(AppLocalizations.of(context)!.retrievingManifestMessage + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle)));
|
|
|
|
|
} else {
|
|
|
|
|
wdgDecorations = Visibility(
|
|
|
|
|
visible: widget.interactive,
|
|
|
|
|
child: LinearProgressIndicator(
|
|
|
|
|
value: Provider.of<ProfileInfoState>(context).downloadProgress(widget.fileKey()),
|
|
|
|
|
color: Provider.of<Settings>(context).theme.defaultButtonActiveColor,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
} else if (flagStarted) {
|
|
|
|
|
// in this case, the download was done in a previous application launch,
|
|
|
|
|
// so we probably have to request an info lookup
|
|
|
|
|
if (!downloadInterrupted) {
|
|
|
|
|
wdgDecorations = Text(AppLocalizations.of(context)!.fileCheckingStatus + '...' + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle));
|
|
|
|
|
// We should have already requested this...
|
|
|
|
|
} else {
|
|
|
|
|
var path = Provider.of<ProfileInfoState>(context).downloadFinalPath(widget.fileKey()) ?? "";
|
|
|
|
|
wdgDecorations = Visibility(
|
|
|
|
|
visible: widget.interactive,
|
|
|
|
|
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
|
|
|
|
Text(AppLocalizations.of(context)!.fileInterrupted + ': ' + path + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle)),
|
|
|
|
|
ElevatedButton(onPressed: _btnResume, child: Text(AppLocalizations.of(context)!.verfiyResumeButton, style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle)))
|
|
|
|
|
]));
|
|
|
|
|
}
|
|
|
|
|
} else if (!senderIsContact) {
|
|
|
|
|
wdgDecorations = Text(AppLocalizations.of(context)!.msgAddToAccept, style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle));
|
|
|
|
|
} else if (!widget.isAuto || Provider.of<MessageMetadata>(context).attributes["file-missing"] == "false") {
|
|
|
|
|
//Note: we need this second case to account for scenarios where a user deletes the downloaded file, we won't automatically
|
|
|
|
|
// fetch it again, so we need to offer the user the ability to restart..
|
|
|
|
|
if (!showFileSharing) {
|
|
|
|
|
wdgDecorations = Text('\u202F');
|
|
|
|
|
} else if (fromMe) {
|
|
|
|
|
wdgDecorations = Text('\u202F');
|
|
|
|
|
} else if (downloadComplete && path != null) {
|
|
|
|
|
// in this case, whatever marked download.complete would have also set the path
|
|
|
|
|
if (myFile != null && Provider.of<Settings>(context).shouldPreview(path)) {
|
|
|
|
|
isPreview = true;
|
|
|
|
|
wdgDecorations = Center(
|
|
|
|
|
widthFactor: 1.0,
|
|
|
|
|
child: MouseRegion(
|
|
|
|
|
cursor: SystemMouseCursors.click,
|
|
|
|
|
child: GestureDetector(
|
|
|
|
|
child: Padding(padding: EdgeInsets.all(1.0), child: getPreview(context)),
|
|
|
|
|
onTap: () {
|
|
|
|
|
pop(context, myFile!, widget.nameSuggestion);
|
|
|
|
|
},
|
|
|
|
|
)));
|
|
|
|
|
} else {
|
|
|
|
|
wdgDecorations = Visibility(
|
|
|
|
|
visible: widget.interactive, child: SelectableText(AppLocalizations.of(context)!.fileSavedTo + ': ' + path + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle)));
|
|
|
|
|
}
|
|
|
|
|
} else if (downloadActive) {
|
|
|
|
|
if (!downloadGotManifest) {
|
|
|
|
|
wdgDecorations = Visibility(
|
|
|
|
|
visible: widget.interactive, child: SelectableText(AppLocalizations.of(context)!.retrievingManifestMessage + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle)));
|
|
|
|
|
} else {
|
|
|
|
|
wdgDecorations = Visibility(
|
|
|
|
|
visible: widget.interactive,
|
|
|
|
|
child: Center(
|
|
|
|
|
widthFactor: 1,
|
|
|
|
|
child: Wrap(children: [
|
|
|
|
|
Padding(
|
|
|
|
|
padding: EdgeInsets.all(5),
|
|
|
|
|
child: ElevatedButton(
|
|
|
|
|
child: Text(AppLocalizations.of(context)!.downloadFileButton + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle)), onPressed: _btnAccept)),
|
|
|
|
|
])));
|
|
|
|
|
} else {
|
|
|
|
|
wdgDecorations = Container();
|
|
|
|
|
child: LinearProgressIndicator(
|
|
|
|
|
value: Provider.of<ProfileInfoState>(context).downloadProgress(widget.fileKey()),
|
|
|
|
|
color: Provider.of<Settings>(context).theme.defaultButtonActiveColor,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
} else if (flagStarted) {
|
|
|
|
|
// in this case, the download was done in a previous application launch,
|
|
|
|
|
// so we probably have to request an info lookup
|
|
|
|
|
if (!downloadInterrupted) {
|
|
|
|
|
wdgDecorations = Text(AppLocalizations.of(context)!.fileCheckingStatus + '...' + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle));
|
|
|
|
|
// We should have already requested this...
|
|
|
|
|
} else {
|
|
|
|
|
var path = Provider.of<ProfileInfoState>(context).downloadFinalPath(widget.fileKey()) ?? "";
|
|
|
|
|
wdgDecorations = Visibility(
|
|
|
|
|
visible: widget.interactive,
|
|
|
|
|
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
|
|
|
|
Text(AppLocalizations.of(context)!.fileInterrupted + ': ' + path + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle)),
|
|
|
|
|
ElevatedButton(onPressed: _btnResume, child: Text(AppLocalizations.of(context)!.verfiyResumeButton, style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle)))
|
|
|
|
|
]));
|
|
|
|
|
}
|
|
|
|
|
} else if (!senderIsContact) {
|
|
|
|
|
wdgDecorations = Text(AppLocalizations.of(context)!.msgAddToAccept, style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle));
|
|
|
|
|
} else if (!widget.isAuto || Provider.of<MessageMetadata>(context).attributes["file-missing"] == "false") {
|
|
|
|
|
//Note: we need this second case to account for scenarios where a user deletes the downloaded file, we won't automatically
|
|
|
|
|
// fetch it again, so we need to offer the user the ability to restart..
|
|
|
|
|
wdgDecorations = Visibility(
|
|
|
|
|
visible: widget.interactive,
|
|
|
|
|
child: Center(
|
|
|
|
|
widthFactor: 1,
|
|
|
|
|
child: Wrap(children: [
|
|
|
|
|
Padding(
|
|
|
|
|
padding: EdgeInsets.all(5),
|
|
|
|
|
child: ElevatedButton(
|
|
|
|
|
child: Text(AppLocalizations.of(context)!.downloadFileButton + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle)), onPressed: _btnAccept)),
|
|
|
|
|
])));
|
|
|
|
|
} else {
|
|
|
|
|
wdgDecorations = Container();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Container(
|
|
|
|
|
constraints: constraints,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeBackgroundColor : Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor,
|
|
|
|
|
border: Border.all(color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeBackgroundColor : Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor, width: 1),
|
|
|
|
|
borderRadius: BorderRadius.only(
|
|
|
|
|
topLeft: Radius.circular(borderRadius),
|
|
|
|
|
topRight: Radius.circular(borderRadius),
|
|
|
|
|
bottomLeft: fromMe ? Radius.circular(borderRadius) : Radius.zero,
|
|
|
|
|
bottomRight: fromMe ? Radius.zero : Radius.circular(borderRadius),
|
|
|
|
|
),
|
|
|
|
|
return Container(
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeBackgroundColor : Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor,
|
|
|
|
|
border: Border.all(color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeBackgroundColor : Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor, width: 1),
|
|
|
|
|
borderRadius: BorderRadius.only(
|
|
|
|
|
topLeft: Radius.circular(borderRadius),
|
|
|
|
|
topRight: Radius.circular(borderRadius),
|
|
|
|
|
bottomLeft: fromMe ? Radius.circular(borderRadius) : Radius.zero,
|
|
|
|
|
bottomRight: fromMe ? Radius.zero : Radius.circular(borderRadius),
|
|
|
|
|
),
|
|
|
|
|
child: Theme(
|
|
|
|
|
data: Theme.of(context).copyWith(
|
|
|
|
|
textSelectionTheme: TextSelectionThemeData(
|
|
|
|
|
cursorColor: Provider.of<Settings>(context).theme.messageSelectionColor,
|
|
|
|
|
selectionColor: Provider.of<Settings>(context).theme.messageSelectionColor,
|
|
|
|
|
selectionHandleColor: Provider.of<Settings>(context).theme.messageSelectionColor),
|
|
|
|
|
),
|
|
|
|
|
child: Theme(
|
|
|
|
|
data: Theme.of(context).copyWith(
|
|
|
|
|
textSelectionTheme: TextSelectionThemeData(
|
|
|
|
|
cursorColor: Provider.of<Settings>(context).theme.messageSelectionColor,
|
|
|
|
|
selectionColor: Provider.of<Settings>(context).theme.messageSelectionColor,
|
|
|
|
|
selectionHandleColor: Provider.of<Settings>(context).theme.messageSelectionColor),
|
|
|
|
|
|
|
|
|
|
// Horrifying Hack: Flutter doesn't give us direct control over system menus but instead picks BG color from TextButtonThemeData ¯\_(ツ)_/¯
|
|
|
|
|
textButtonTheme: TextButtonThemeData(
|
|
|
|
|
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Provider.of<Settings>(context).theme.menuBackgroundColor)),
|
|
|
|
|
),
|
|
|
|
|
// Horrifying Hack: Flutter doesn't give us direct control over system menus but instead picks BG color from TextButtonThemeData ¯\_(ツ)_/¯
|
|
|
|
|
textButtonTheme: TextButtonThemeData(
|
|
|
|
|
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Provider.of<Settings>(context).theme.menuBackgroundColor)),
|
|
|
|
|
),
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: EdgeInsets.all(9.0),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: fromMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
|
|
|
|
mainAxisAlignment: fromMe ? MainAxisAlignment.end : MainAxisAlignment.start,
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
children: [
|
|
|
|
|
wdgSender,
|
|
|
|
|
isPreview
|
|
|
|
|
? Container(
|
|
|
|
|
width: 0,
|
|
|
|
|
padding: EdgeInsets.zero,
|
|
|
|
|
margin: EdgeInsets.zero,
|
|
|
|
|
)
|
|
|
|
|
: wdgMessage,
|
|
|
|
|
wdgDecorations,
|
|
|
|
|
messageStatusWidget
|
|
|
|
|
]),
|
|
|
|
|
)));
|
|
|
|
|
});
|
|
|
|
|
),
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: EdgeInsets.all(9.0),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: fromMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
|
|
|
|
mainAxisAlignment: fromMe ? MainAxisAlignment.end : MainAxisAlignment.start,
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
children: [
|
|
|
|
|
wdgSender,
|
|
|
|
|
isPreview
|
|
|
|
|
? Container(
|
|
|
|
|
width: 0,
|
|
|
|
|
padding: EdgeInsets.zero,
|
|
|
|
|
margin: EdgeInsets.zero,
|
|
|
|
|
)
|
|
|
|
|
: wdgMessage,
|
|
|
|
|
wdgDecorations,
|
|
|
|
|
messageStatusWidget
|
|
|
|
|
]),
|
|
|
|
|
)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _btnAccept() async {
|
|
|
|
@ -322,41 +318,27 @@ class FileBubbleState extends State<FileBubble> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Construct an file chrome for the sender
|
|
|
|
|
Widget senderFileChrome(String chrome, String fileName, String rootHash, int fileSize) {
|
|
|
|
|
Widget senderFileChrome(String chrome, String fileName, String rootHash) {
|
|
|
|
|
var settings = Provider.of<Settings>(context);
|
|
|
|
|
return ListTile(
|
|
|
|
|
visualDensity: VisualDensity.compact,
|
|
|
|
|
title: Wrap(direction: Axis.horizontal, alignment: WrapAlignment.start, children: [
|
|
|
|
|
SelectableText(
|
|
|
|
|
chrome + '\u202F',
|
|
|
|
|
style: settings.scaleFonts(defaultMessageTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
maxLines: 2,
|
|
|
|
|
textWidthBasis: TextWidthBasis.longestLine,
|
|
|
|
|
),
|
|
|
|
|
SelectableText(
|
|
|
|
|
fileName + '\u202F',
|
|
|
|
|
style:
|
|
|
|
|
settings.scaleFonts(defaultMessageTextStyle.copyWith(overflow: TextOverflow.ellipsis, fontWeight: FontWeight.bold, color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
textWidthBasis: TextWidthBasis.parent,
|
|
|
|
|
maxLines: 2,
|
|
|
|
|
),
|
|
|
|
|
SelectableText(
|
|
|
|
|
prettyBytes(fileSize) + '\u202F' + '\n',
|
|
|
|
|
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
maxLines: 2,
|
|
|
|
|
)
|
|
|
|
|
]),
|
|
|
|
|
contentPadding: EdgeInsets.all(1.0),
|
|
|
|
|
title: SelectableText(
|
|
|
|
|
fileName + '\u202F',
|
|
|
|
|
style:
|
|
|
|
|
settings.scaleFonts(defaultMessageTextStyle.copyWith(overflow: TextOverflow.ellipsis, fontWeight: FontWeight.bold, color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
textWidthBasis: TextWidthBasis.longestLine,
|
|
|
|
|
maxLines: 2,
|
|
|
|
|
),
|
|
|
|
|
subtitle: SelectableText(
|
|
|
|
|
'sha512: ' + rootHash + '\u202F',
|
|
|
|
|
prettyBytes(widget.fileSize) + '\u202F' + '\n' + 'sha512: ' + rootHash + '\u202F',
|
|
|
|
|
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(fontFamily: "RobotoMono", color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
maxLines: 4,
|
|
|
|
|
textWidthBasis: TextWidthBasis.parent,
|
|
|
|
|
textWidthBasis: TextWidthBasis.longestLine,
|
|
|
|
|
),
|
|
|
|
|
leading: Icon(CwtchIcons.attached_file_3, size: 32, color: Provider.of<Settings>(context).theme.messageFromMeTextColor));
|
|
|
|
|
leading: FittedBox(child: Icon(CwtchIcons.attached_file_3, size: 32, color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Construct an file chrome
|
|
|
|
@ -364,46 +346,33 @@ class FileBubbleState extends State<FileBubble> {
|
|
|
|
|
var settings = Provider.of<Settings>(context);
|
|
|
|
|
return ListTile(
|
|
|
|
|
visualDensity: VisualDensity.compact,
|
|
|
|
|
title: Wrap(direction: Axis.horizontal, alignment: WrapAlignment.start, children: [
|
|
|
|
|
SelectableText(
|
|
|
|
|
chrome + '\u202F',
|
|
|
|
|
style: settings.scaleFonts(defaultMessageTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
maxLines: 2,
|
|
|
|
|
textWidthBasis: TextWidthBasis.longestLine,
|
|
|
|
|
),
|
|
|
|
|
SelectableText(
|
|
|
|
|
fileName + '\u202F',
|
|
|
|
|
style: settings
|
|
|
|
|
.scaleFonts(defaultMessageTextStyle.copyWith(overflow: TextOverflow.ellipsis, fontWeight: FontWeight.bold, color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
textWidthBasis: TextWidthBasis.parent,
|
|
|
|
|
maxLines: 2,
|
|
|
|
|
),
|
|
|
|
|
SelectableText(
|
|
|
|
|
AppLocalizations.of(context)!.labelFilesize + ': ' + prettyBytes(fileSize) + '\u202F' + '\n',
|
|
|
|
|
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
maxLines: 2,
|
|
|
|
|
)
|
|
|
|
|
]),
|
|
|
|
|
contentPadding: EdgeInsets.all(1.0),
|
|
|
|
|
title: SelectableText(
|
|
|
|
|
fileName + '\u202F',
|
|
|
|
|
style:
|
|
|
|
|
settings.scaleFonts(defaultMessageTextStyle.copyWith(overflow: TextOverflow.ellipsis, fontWeight: FontWeight.bold, color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
textWidthBasis: TextWidthBasis.longestLine,
|
|
|
|
|
maxLines: 2,
|
|
|
|
|
),
|
|
|
|
|
subtitle: SelectableText(
|
|
|
|
|
'sha512: ' + rootHash + '\u202F',
|
|
|
|
|
prettyBytes(widget.fileSize) + '\u202F' + '\n' + 'sha512: ' + rootHash + '\u202F',
|
|
|
|
|
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(fontFamily: "RobotoMono", color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
maxLines: 4,
|
|
|
|
|
textWidthBasis: TextWidthBasis.parent,
|
|
|
|
|
textWidthBasis: TextWidthBasis.longestLine,
|
|
|
|
|
),
|
|
|
|
|
leading: Icon(CwtchIcons.attached_file_3, size: 32, color: Provider.of<Settings>(context).theme.messageFromOtherTextColor),
|
|
|
|
|
trailing: Visibility(
|
|
|
|
|
visible: speed != "0 B/s",
|
|
|
|
|
child: SelectableText(
|
|
|
|
|
speed + '\u202F',
|
|
|
|
|
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
maxLines: 1,
|
|
|
|
|
textWidthBasis: TextWidthBasis.longestLine,
|
|
|
|
|
)),
|
|
|
|
|
leading: FittedBox(child: Icon(CwtchIcons.attached_file_3, size: 32, color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
|
|
|
|
|
// Note: not using Visible here because we want to shrink this to nothing when not in use...
|
|
|
|
|
trailing: speed == "0 B/s"
|
|
|
|
|
? null
|
|
|
|
|
: SelectableText(
|
|
|
|
|
speed + '\u202F',
|
|
|
|
|
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
maxLines: 1,
|
|
|
|
|
textWidthBasis: TextWidthBasis.longestLine,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|