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

inbox: Implement workable dark theme #859

Merged
merged 3 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
51 changes: 26 additions & 25 deletions lib/widgets/inbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,11 @@ abstract class _HeaderItem extends StatelessWidget {

@override
Widget build(BuildContext context) {
final designVariables = DesignVariables.of(context);
return Material(
// TODO(#95) need dark-theme color
color: collapsed ? Colors.white : uncollapsedBackgroundColor(context),
color: collapsed
? designVariables.background // TODO(design) check if this is the right variable
: uncollapsedBackgroundColor(context),
child: InkWell(
// TODO use onRowTap to handle taps that are not on the collapse button.
// Probably we should give the collapse button a 44px or 48px square
Expand All @@ -258,8 +260,7 @@ abstract class _HeaderItem extends StatelessWidget {
onTap: onCollapseButtonTap,
child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
Padding(padding: const EdgeInsets.all(10),
// TODO(#95) need dark-theme color
child: Icon(size: 20, color: const Color(0x7F1D2E48),
child: Icon(size: 20, color: designVariables.sectionCollapseIcon,
collapsed ? ZulipIcons.arrow_right : ZulipIcons.arrow_down)),
Icon(size: 18,
color: collapsed
Expand All @@ -270,11 +271,11 @@ abstract class _HeaderItem extends StatelessWidget {
Expanded(child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Text(
style: const TextStyle(
style: TextStyle(
fontSize: 17,
height: (20 / 17),
// TODO(#95) need dark-theme color
color: Color(0xFF222222),
// TODO(design) check if this is the right variable
color: designVariables.labelMenuButton,
).merge(weightVariableTextStyle(context, wght: 600)),
maxLines: 1,
overflow: TextOverflow.ellipsis,
Expand Down Expand Up @@ -302,11 +303,11 @@ class _AllDmsHeaderItem extends _HeaderItem {
@override String get title => 'Direct messages'; // TODO(i18n)
@override IconData get icon => ZulipIcons.user;

// TODO(#95) need dark-theme colors
@override Color collapsedIconColor(context) => const Color(0xFF222222);
@override Color uncollapsedIconColor(context) => const Color(0xFF222222);
// TODO(design) check if this is the right variable for these
@override Color collapsedIconColor(context) => DesignVariables.of(context).labelMenuButton;
@override Color uncollapsedIconColor(context) => DesignVariables.of(context).labelMenuButton;

@override Color uncollapsedBackgroundColor(context) => const HSLColor.fromAHSL(1, 46, 0.35, 0.93).toColor();
@override Color uncollapsedBackgroundColor(context) => DesignVariables.of(context).dmHeaderBg;
@override Color? unreadCountBadgeBackgroundColor(context) => null;

@override Future<void> onCollapseButtonTap() async {
Expand Down Expand Up @@ -368,6 +369,8 @@ class _DmItem extends StatelessWidget {
final store = PerAccountStoreWidget.of(context);
final selfUser = store.users[store.selfUserId]!;

final designVariables = DesignVariables.of(context);

final title = switch (narrow.otherRecipientIds) { // TODO dedupe with [RecentDmConversationsItem]
[] => selfUser.fullName,
[var otherUserId] => store.users[otherUserId]?.fullName ?? '(unknown user)',
Expand All @@ -379,8 +382,7 @@ class _DmItem extends StatelessWidget {
};

return Material(
// TODO(#95) need dark-theme color
color: Colors.white,
color: designVariables.background, // TODO(design) check if this is the right variable
child: InkWell(
onTap: () {
Navigator.push(context,
Expand All @@ -392,11 +394,11 @@ class _DmItem extends StatelessWidget {
Expanded(child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Text(
style: const TextStyle(
style: TextStyle(
fontSize: 17,
height: (20 / 17),
// TODO(#95) need dark-theme color
color: Color(0xFF222222),
// TODO(design) check if this is the right variable
color: designVariables.labelMenuButton,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
Expand Down Expand Up @@ -501,9 +503,10 @@ class _TopicItem extends StatelessWidget {
final store = PerAccountStoreWidget.of(context);
final subscription = store.subscriptions[streamId]!;

final designVariables = DesignVariables.of(context);

return Material(
// TODO(#95) need dark-theme color
color: Colors.white,
color: designVariables.background, // TODO(design) check if this is the right variable
child: InkWell(
onTap: () {
final narrow = TopicNarrow(streamId, topic);
Expand All @@ -516,11 +519,11 @@ class _TopicItem extends StatelessWidget {
Expanded(child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Text(
style: const TextStyle(
style: TextStyle(
fontSize: 17,
height: (20 / 17),
// TODO(#95) need dark-theme color
color: Color(0xFF222222),
// TODO(design) check if this is the right variable
color: designVariables.labelMenuButton,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
Expand All @@ -538,15 +541,13 @@ class _TopicItem extends StatelessWidget {
class _AtMentionMarker extends StatelessWidget {
const _AtMentionMarker();

// TODO(#95) need dark-theme color
static final markerColor = const HSLColor.fromAHSL(0.5, 0, 0, 0.2).toColor();

@override
Widget build(BuildContext context) {
final designVariables = DesignVariables.of(context);
// Design for at-mention marker based on Figma screen:
// https://www.figma.com/file/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?type=design&node-id=224-16386&mode=design&t=JsNndFQ8fKFH0SjS-0
return Padding(
padding: const EdgeInsetsDirectional.only(end: 4),
child: Icon(ZulipIcons.at_sign, size: 14, color: markerColor));
child: Icon(ZulipIcons.at_sign, size: 14, color: designVariables.atMentionMarker));
}
}
37 changes: 37 additions & 0 deletions lib/widgets/theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,48 +129,65 @@ const kZulipBrandColor = Color.fromRGBO(0x64, 0x92, 0xfe, 1);
class DesignVariables extends ThemeExtension<DesignVariables> {
DesignVariables.light() :
this._(
background: const Color(0xffffffff),
bgCounterUnread: const Color(0xff666699).withOpacity(0.15),
bgTopBar: const Color(0xfff5f5f5),
borderBar: const Color(0x33000000),
icon: const Color(0xff666699),
labelCounterUnread: const Color(0xff222222),
labelMenuButton: const Color(0xff222222),
mainBackground: const Color(0xfff0f0f0),
title: const Color(0xff1a1a1a),
channelColorSwatches: ChannelColorSwatches.light,
atMentionMarker: const HSLColor.fromAHSL(0.5, 0, 0, 0.2).toColor(),
dmHeaderBg: const HSLColor.fromAHSL(1, 46, 0.35, 0.93).toColor(),
loginOrDivider: const Color(0xffdedede),
loginOrDividerText: const Color(0xff575757),
sectionCollapseIcon: const Color(0x7f1e2e48),
star: const HSLColor.fromAHSL(0.5, 47, 1, 0.41).toColor(),
unreadCountBadgeTextForChannel: Colors.black.withOpacity(0.9),
);

DesignVariables.dark() :
this._(
background: const Color(0xff000000),
bgCounterUnread: const Color(0xff666699).withOpacity(0.37),
bgTopBar: const Color(0xff242424),
borderBar: Colors.black.withOpacity(0.41),
icon: const Color(0xff7070c2),
labelCounterUnread: const Color(0xffffffff).withOpacity(0.7),
labelMenuButton: const Color(0xffffffff).withOpacity(0.85),
mainBackground: const Color(0xff1d1d1d),
title: const Color(0xffffffff),
channelColorSwatches: ChannelColorSwatches.dark,
// TODO(#95) need proper dark-theme color (this is ad hoc)
atMentionMarker: const HSLColor.fromAHSL(0.4, 0, 0, 1).toColor(),
dmHeaderBg: const HSLColor.fromAHSL(1, 46, 0.15, 0.2).toColor(),
loginOrDivider: const Color(0xff424242),
loginOrDividerText: const Color(0xffa8a8a8),
// TODO(#95) need proper dark-theme color (this is ad hoc)
sectionCollapseIcon: const Color(0x7fb6c8e2),
// TODO(#95) unchanged in dark theme?
star: const HSLColor.fromAHSL(0.5, 47, 1, 0.41).toColor(),
unreadCountBadgeTextForChannel: Colors.white.withOpacity(0.9),
);

DesignVariables._({
required this.background,
required this.bgCounterUnread,
required this.bgTopBar,
required this.borderBar,
required this.icon,
required this.labelCounterUnread,
required this.labelMenuButton,
required this.mainBackground,
required this.title,
required this.channelColorSwatches,
required this.atMentionMarker,
required this.dmHeaderBg,
required this.loginOrDivider,
required this.loginOrDividerText,
required this.sectionCollapseIcon,
required this.star,
required this.unreadCountBadgeTextForChannel,
});
Expand All @@ -185,49 +202,64 @@ class DesignVariables extends ThemeExtension<DesignVariables> {
return extension!;
}

final Color background;
final Color bgCounterUnread;
final Color bgTopBar;
final Color borderBar;
final Color icon;
final Color labelCounterUnread;
final Color labelMenuButton;
final Color mainBackground;
final Color title;

// Not exactly from the Figma design, but from Vlad anyway.
final ChannelColorSwatches channelColorSwatches;

// Not named variables in Figma; taken from older Figma drafts, or elsewhere.
final Color atMentionMarker;
final Color dmHeaderBg;
final Color loginOrDivider; // TODO(#95) need proper dark-theme color (this is ad hoc)
final Color loginOrDividerText; // TODO(#95) need proper dark-theme color (this is ad hoc)
final Color sectionCollapseIcon;
final Color star;
final Color unreadCountBadgeTextForChannel;

@override
DesignVariables copyWith({
Color? background,
Color? bgCounterUnread,
Color? bgTopBar,
Color? borderBar,
Color? icon,
Color? labelCounterUnread,
Color? labelMenuButton,
Color? mainBackground,
Color? title,
ChannelColorSwatches? channelColorSwatches,
Color? atMentionMarker,
Color? dmHeaderBg,
Color? loginOrDivider,
Color? loginOrDividerText,
Color? sectionCollapseIcon,
Color? star,
Color? unreadCountBadgeTextForChannel,
}) {
return DesignVariables._(
background: background ?? this.background,
bgCounterUnread: bgCounterUnread ?? this.bgCounterUnread,
bgTopBar: bgTopBar ?? this.bgTopBar,
borderBar: borderBar ?? this.borderBar,
icon: icon ?? this.icon,
labelCounterUnread: labelCounterUnread ?? this.labelCounterUnread,
labelMenuButton: labelMenuButton ?? this.labelMenuButton,
mainBackground: mainBackground ?? this.mainBackground,
title: title ?? this.title,
channelColorSwatches: channelColorSwatches ?? this.channelColorSwatches,
atMentionMarker: atMentionMarker ?? this.atMentionMarker,
dmHeaderBg: dmHeaderBg ?? this.dmHeaderBg,
loginOrDivider: loginOrDivider ?? this.loginOrDivider,
loginOrDividerText: loginOrDividerText ?? this.loginOrDividerText,
sectionCollapseIcon: sectionCollapseIcon ?? this.sectionCollapseIcon,
star: star ?? this.star,
unreadCountBadgeTextForChannel: unreadCountBadgeTextForChannel ?? this.unreadCountBadgeTextForChannel,
);
Expand All @@ -239,16 +271,21 @@ class DesignVariables extends ThemeExtension<DesignVariables> {
return this;
}
return DesignVariables._(
background: Color.lerp(background, other.background, t)!,
bgCounterUnread: Color.lerp(bgCounterUnread, other.bgCounterUnread, t)!,
bgTopBar: Color.lerp(bgTopBar, other.bgTopBar, t)!,
borderBar: Color.lerp(borderBar, other.borderBar, t)!,
icon: Color.lerp(icon, other.icon, t)!,
labelCounterUnread: Color.lerp(labelCounterUnread, other.labelCounterUnread, t)!,
labelMenuButton: Color.lerp(labelMenuButton, other.labelMenuButton, t)!,
mainBackground: Color.lerp(mainBackground, other.mainBackground, t)!,
title: Color.lerp(title, other.title, t)!,
channelColorSwatches: ChannelColorSwatches.lerp(channelColorSwatches, other.channelColorSwatches, t),
atMentionMarker: Color.lerp(atMentionMarker, other.atMentionMarker, t)!,
dmHeaderBg: Color.lerp(dmHeaderBg, other.dmHeaderBg, t)!,
loginOrDivider: Color.lerp(loginOrDivider, other.loginOrDivider, t)!,
loginOrDividerText: Color.lerp(loginOrDividerText, other.loginOrDividerText, t)!,
sectionCollapseIcon: Color.lerp(sectionCollapseIcon, other.sectionCollapseIcon, t)!,
star: Color.lerp(star, other.star, t)!,
unreadCountBadgeTextForChannel: Color.lerp(unreadCountBadgeTextForChannel, other.unreadCountBadgeTextForChannel, t)!,
);
Expand Down