feat: adiciona menu Desenvolvedor as configuracoes, nova modal Sobre e icones da marca TatuChat
Some checks failed
Main Deploy Workflow / deploy_web (push) Has been cancelled
Main Deploy Workflow / deploy_playstore_internal (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled

- Submenu Desenvolvedor em Configuracoes (Sobre o servidor, Registros, Variaveis e ambiente)
- Modal Sobre maior com logo, descricao com link e rodape (codigo-fonte, licenca, fechar)
- Descricao legivel no tema dark
- Drawer com a logo do projeto e links de support/formulario atualizados
- flutter_launcher_icons: regenera icones Android (mipmap + adaptive), Web, iOS, macOS, Windows
This commit is contained in:
2026-09-20 18:16:35 -03:00
parent 6c689d1f34
commit 762178d9f9
55 changed files with 221 additions and 191 deletions

View File

@@ -5,12 +5,13 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:material_ui/material_ui.dart';
import 'package:material_ui/material_ui.dart' as m show Dialog, showDialog;
import 'package:package_info_plus/package_info_plus.dart';
import 'package:tatchat/config/setting_keys.dart';
import 'package:tatchat/l10n/l10n.dart';
import 'package:flutter/foundation.dart';
import 'package:go_router/go_router.dart';
import 'package:material_ui/material_ui.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../config/app_config.dart';
@@ -56,53 +57,107 @@ abstract class PlatformInfos {
return version;
}
static const String aboutDescription =
'O TatuChat é um cliente de mensagens instantâneas focado em '
'privacidade, simplicidade e código aberto, desenvolvido como um fork do '
'aclamado projeto FluffyChat. Utilizando o protocolo descentralizado '
'Matrix, ele oferece criptografia de ponta a ponta (E2EE) para proteger '
'conversas, arquivos e mídias. Além do bate-papo tradicional, o projeto '
'se destaca por recursos como canais de transmissão, organização em '
'espaços, murais visuais em formato de grid e suporte a mini-apps '
'desenvolvidos pela comunidade. Acesse Aqui. '
'https://tatuchat.weltonmoura.com.br/home/';
static Future<void> showDialog(BuildContext context) async {
final l10n = L10n.of(context);
final version = await PlatformInfos.getVersion();
if (!context.mounted) return;
showAboutDialog(
final theme = Theme.of(context);
final size = MediaQuery.sizeOf(context);
await m.showDialog<void>(
context: context,
children: [
Text(l10n.versionWithNumber(version)),
TextButton.icon(
onPressed: () => launchUrlString(AppConfig.sourceCodeUrl),
icon: const Icon(Icons.source_outlined),
label: Text(l10n.sourceCode),
builder: (context) => m.Dialog(
insetPadding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 40,
),
Builder(
builder: (innerContext) {
return TextButton.icon(
onPressed: () {
context.go('/logs');
Navigator.of(innerContext).pop();
},
icon: const Icon(Icons.list_outlined),
label: Text(l10n.logs),
);
},
),
Builder(
builder: (innerContext) {
return TextButton.icon(
onPressed: () {
context.go('/configs');
Navigator.of(innerContext).pop();
},
icon: const Icon(Icons.settings_applications_outlined),
label: Text(l10n.advancedConfigs),
);
},
),
],
applicationIcon: ClipRRect(
borderRadius: BorderRadius.circular(64),
child: Image.asset(
'./assets/logo/mini/logo_mini.png',
width: 64,
height: 64,
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: 720,
maxHeight: size.height * 0.88,
),
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: .min,
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
mainAxisSize: .min,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(32),
child: Image.asset(
'./assets/logo/mini/logo_mini.png',
width: 96,
height: 96,
),
),
const SizedBox(height: 24),
Text(
AppSettings.applicationName.value,
textAlign: TextAlign.center,
style: theme.textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 24),
Linkify(
text: aboutDescription,
textAlign: TextAlign.center,
style: TextStyle(
color: theme.colorScheme.onSurface,
),
options: const LinkifyOptions(humanize: false),
linkStyle: TextStyle(
color: theme.colorScheme.primary,
decorationColor: theme.colorScheme.primary,
),
onOpen: (link) => launchUrlString(link.url),
),
],
),
),
),
const SizedBox(height: 8),
const Divider(),
const SizedBox(height: 8),
Wrap(
alignment: WrapAlignment.end,
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 8,
runSpacing: 4,
children: [
TextButton.icon(
onPressed: () => launchUrlString(AppConfig.sourceCodeUrl),
icon: const Icon(Icons.source_outlined),
label: Text(l10n.sourceCode),
),
TextButton.icon(
onPressed: () => launchUrlString(AppConfig.licenseUrl),
icon: const Icon(Icons.description_outlined),
label: Text(l10n.licence),
),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(l10n.close),
),
],
),
],
),
),
),
),
applicationName: AppSettings.applicationName.value,
);
}
}