Files
GitJournal/lib/widgets/app_drawer_header.dart
Vishesh Handa 7fd1c99287 Use Provider's context.read/watch
Instead of the legacy Provider.of. Less scope of bugs this way and the
code is so much nicer to read.
2023-12-06 08:20:40 +01:00

225 lines
5.6 KiB
Dart

/*
* SPDX-FileCopyrightText: 2019-2021 Vishesh Handa <me@vhanda.in>
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:function_types/function_types.dart';
import 'package:gitjournal/l10n.dart';
import 'package:gitjournal/repository.dart';
import 'package:gitjournal/repository_manager.dart';
import 'package:gitjournal/settings/app_config.dart';
import 'package:gitjournal/settings/settings.dart';
import 'package:provider/provider.dart';
import 'package:time/time.dart';
class AppDrawerHeader extends StatelessWidget {
final Func0<void> repoListToggled;
const AppDrawerHeader({
required this.repoListToggled,
});
@override
Widget build(BuildContext context) {
var appConfig = context.watch<AppConfig>();
var top = Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/icon/icon.png'),
),
),
child: SizedBox(width: 64, height: 64),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 8, 0),
child: ThemeSwitcherButton(),
),
],
);
var currentRepo = _CurrentRepo(
repoListToggled: repoListToggled,
);
var header = DrawerHeader(
margin: const EdgeInsets.all(0.0),
decoration: BoxDecoration(
color: Theme.of(context).highlightColor,
),
padding: const EdgeInsets.fromLTRB(16, 16, 8, 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
top,
currentRepo,
],
),
);
if (!appConfig.proMode) {
return header;
}
var isDesktop = Platform.isLinux || Platform.isWindows || Platform.isMacOS;
return Banner(
message: isDesktop ? context.loc.beta : context.loc.pro,
location: BannerLocation.topStart,
color: Theme.of(context).colorScheme.secondary,
child: header,
);
}
}
class _CurrentRepo extends StatefulWidget {
const _CurrentRepo({
required this.repoListToggled,
});
final Func0<void> repoListToggled;
@override
__CurrentRepoState createState() => __CurrentRepoState();
}
class __CurrentRepoState extends State<_CurrentRepo>
with SingleTickerProviderStateMixin {
late Animation<double> _animation;
late AnimationController _controller;
var _gitRemoteUrl = "";
var _repoFolderName = "";
@override
void initState() {
super.initState();
_controller = AnimationController(duration: 250.milliseconds, vsync: this);
_animation = Tween(begin: 0.0, end: 0.5).animate(CurvedAnimation(
parent: _controller,
curve: Curves.linear,
));
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_fetchRepoInfo();
var textTheme = Theme.of(context).textTheme;
var w = Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(_repoFolderName, style: textTheme.titleLarge),
const SizedBox(height: 8.0),
Text(
_gitRemoteUrl,
style: textTheme.titleSmall,
overflow: TextOverflow.clip,
maxLines: 1,
),
const SizedBox(height: 8.0),
],
),
),
RotationTransition(
turns: _animation,
child: IconButton(
icon: const FaIcon(FontAwesomeIcons.angleDown),
onPressed: _pressed,
),
),
],
);
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: _pressed,
child: w,
);
}
void _pressed() {
if (_controller.isCompleted) {
_controller.reverse(from: 1.0);
} else {
_controller.forward(from: 0.0);
}
widget.repoListToggled();
}
Future<void> _fetchRepoInfo() async {
if (_repoFolderName.isNotEmpty) {
return;
}
var repoManager = context.watch<RepositoryManager>();
_repoFolderName = repoManager.repoFolderName(repoManager.currentId);
if (repoManager.currentRepoError != null) {
_gitRemoteUrl = "Error";
return;
}
var repo = context.watch<GitJournalRepo>();
var remoteConfigs = await repo.remoteConfigs();
if (!mounted) return;
if (remoteConfigs.isEmpty) {
setState(() {
_gitRemoteUrl = context.loc.drawerRemote;
});
return;
}
setState(() {
_gitRemoteUrl = remoteConfigs.first.url;
var i = _gitRemoteUrl.indexOf('@');
if (i != -1 && i + 1 < _gitRemoteUrl.length) {
_gitRemoteUrl = _gitRemoteUrl.substring(i + 1);
}
});
}
}
class ThemeSwitcherButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
child: const FaIcon(FontAwesomeIcons.solidMoon),
onTap: () {
var theme = Theme.of(context);
var settings = context.read<Settings>();
if (theme.brightness == Brightness.light) {
settings.theme = SettingsTheme.Dark;
} else {
settings.theme = SettingsTheme.Light;
}
settings.save();
},
);
}
}