Skip to content

Commit

Permalink
Develop (#234)
Browse files Browse the repository at this point in the history
* replace akaricons with flutter lib and add delete icon - resolves #230

* general UI fixes

* increase ss resolution macos

* [skip-ci] add Integration Tests badge

* Add device screenshots [bot]

Co-authored-by: maxisme <[email protected]>
  • Loading branch information
maxisme and maxisme authored Apr 2, 2022
1 parent eb82052 commit e453fba
Show file tree
Hide file tree
Showing 81 changed files with 156 additions and 199 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ss.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ jobs:
script: |
echo "${{ secrets.B64_DEV_ENV }}" | base64 --decode > .env
# increase macos resolution
system_profiler SPDisplaysDataType | grep Resolution
"/Library/Application Support/VMware Tools/vmware-resolutionSet" 2560 1440
system_profiler SPDisplaysDataType | grep Resolution
flutter config --enable-macos-desktop
flutter devices
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
## App | [Website](https://github.com/maxisme/notifi.it) | [Backend](https://github.com/maxisme/notifi-backend)

[![style: lint](https://img.shields.io/badge/lint-flutter-4BC0F5)](https://pub.dev/packages/lint)
[![CI](https://github.com/maxisme/notifi/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/maxisme/notifi/actions/workflows/ci.yml)
[![Master](https://github.com/maxisme/notifi/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/maxisme/notifi/actions/workflows/ci.yml)
[![Integration Tests](https://github.com/maxisme/notifi/actions/workflows/it.yml/badge.svg)](https://github.com/maxisme/notifi/actions/workflows/it.yml)

# Run locally

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed fonts/Akaricons.ttf
Binary file not shown.
Binary file modified ios/fastlane/screenshots/en-GB/0_APP_IPAD_PRO_129_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/0_APP_IPHONE_55_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/0_APP_IPHONE_65_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/0_APP_ipadPro129-3rd-gen_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/1_APP_IPAD_PRO_129_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/1_APP_IPHONE_55_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/1_APP_IPHONE_65_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/1_APP_ipadPro129-3rd-gen_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/2_APP_IPAD_PRO_129_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/2_APP_IPHONE_55_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/2_APP_IPHONE_65_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/fastlane/screenshots/en-GB/2_APP_ipadPro129-3rd-gen_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
129 changes: 62 additions & 67 deletions lib/notifications/notification.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import 'dart:async';
import 'dart:io';

import 'package:akar_icons_flutter/akar_icons_flutter.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:intl/intl.dart' as i;
import 'package:json_annotation/json_annotation.dart';
import 'package:notifi/notifications/notifis.dart';
import 'package:notifi/utils/icons.dart';
import 'package:notifi/utils/pallete.dart';
import 'package:notifi/utils/utils.dart';
import 'package:provider/provider.dart';
Expand Down Expand Up @@ -95,7 +93,8 @@ class NotificationUIState extends State<NotificationUI>
final GlobalKey _messageKey = GlobalKey();
final ValueNotifier<String> _timeStr = ValueNotifier<String>('');
Timer timer;
SlideActionType mouseSliderAction;

double iconSize = 15.0;

@override
void setState(Function fn) {
Expand All @@ -120,7 +119,6 @@ class NotificationUIState extends State<NotificationUI>

@override
void dispose() {
mouseSliderAction = null;
timer?.cancel();
super.dispose();
}
Expand All @@ -129,7 +127,6 @@ class NotificationUIState extends State<NotificationUI>
Widget build(BuildContext context) {
return Consumer<Notifications>(builder:
(BuildContext context, Notifications reloadTable, Widget child) {
const double iconSize = 15.0;
String title = widget.title;
String message = widget.message;
int messageMaxLines = 3;
Expand Down Expand Up @@ -195,8 +192,8 @@ class NotificationUIState extends State<NotificationUI>
},
child: Container(
padding: const EdgeInsets.only(top: 7.0),
child: const Icon(
Akaricons.link,
child: Icon(
AkarIcons.link_chain,
size: iconSize,
color: MyColour.grey,
)));
Expand Down Expand Up @@ -239,6 +236,8 @@ class NotificationUIState extends State<NotificationUI>
timePaddingBottom = 1;
timePaddingTop = 4;
}

// NOTIFICATION
final Container slideNotification = Container(
color: Colors.transparent,
padding: const EdgeInsets.only(
Expand Down Expand Up @@ -273,8 +272,8 @@ class NotificationUIState extends State<NotificationUI>
child: Container(
padding:
const EdgeInsets.only(top: 2.0),
child: const Icon(
Akaricons.check,
child: Icon(
AkarIcons.check,
size: iconSize,
color: MyColour.grey,
))),
Expand All @@ -292,8 +291,8 @@ class NotificationUIState extends State<NotificationUI>
const EdgeInsets.only(top: 7.0),
child: Icon(
widget.isExpanded
? Akaricons.reduce
: Akaricons.enlarge,
? AkarIcons.reduce
: AkarIcons.enlarge,
size: iconSize,
color: MyColour.grey,
)))
Expand All @@ -311,25 +310,51 @@ class NotificationUIState extends State<NotificationUI>
key: _columnKey,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// TITLE
SelectableText(title, key: _titleKey,
onTap: () {
setState(() {
if (!widget.isExpanded) {
widget.toggleExpand(
context, widget.index);
}
});
},
scrollPhysics:
const NeverScrollableScrollPhysics(),
style: Theme.of(context)
.textTheme
.headline1
.copyWith(color: titleColour),
textAlign: TextAlign.left,
minLines: 1,
maxLines: titleMaxLines),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// TITLE
Expanded(
child: SelectableText(title,
key: _titleKey, onTap: () {
setState(() {
if (!widget.isExpanded) {
widget.toggleExpand(
context, widget.index);
}
});
},
scrollPhysics:
// ignore: lines_longer_than_80_chars
const NeverScrollableScrollPhysics(),
style: Theme.of(context)
.textTheme
.headline1
.copyWith(color: titleColour),
textAlign: TextAlign.left,
minLines: 1,
maxLines: titleMaxLines),
),
if (Platform.isMacOS || Platform.isLinux)
Padding(
padding:
const EdgeInsets.only(top: 2.0),
child: InkWell(
onTap: () {
setState(() {
Provider.of<Notifications>(
context,
listen: false)
.delete(widget.index);
});
},
child:
Icon(AkarIcons.cross, size: 10),
)),
],
),

// TIME
Padding(
Expand All @@ -356,40 +381,6 @@ class NotificationUIState extends State<NotificationUI>
]),
))
]))));

if (Platform.isMacOS || Platform.isLinux) {
final SlidableState slider = Slidable.of(context);
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final double paddingArea = constraints.maxWidth - padding - 5;
return MouseRegion(
onHover: (PointerHoverEvent event) {
SlideActionType actionType;
if (event.position.dx > paddingArea) {
mouseSliderAction = actionType = SlideActionType.secondary;
} else if (event.position.dx <= padding + 5) {
mouseSliderAction = actionType = SlideActionType.primary;
} else {
Slidable.of(context).close();
mouseSliderAction = null;
}

// Add delay to make sure mouse is in area for a set amount of
// time
Future<dynamic>.delayed(const Duration(milliseconds: 100), () {
if (mouseSliderAction != null &&
mouseSliderAction == actionType &&
slider != null) {
slider.open(actionType: actionType);
}
});
},
onExit: (_) {
mouseSliderAction = null;
},
child: slideNotification);
});
}
return GestureDetector(
onLongPress: () {
setState(() {
Expand All @@ -407,13 +398,17 @@ class NotificationUIState extends State<NotificationUI>
// prevent check if can expand when window is scaling up
if (Platform.isMacOS && _columnKey.currentContext.size.width <= 123) return;

double maxWidth = _columnKey.currentContext.size.width;
// account for icon
if (Platform.isMacOS || Platform.isLinux) maxWidth -= iconSize;

if (_columnKey.currentContext != null &&
hasTextOverflow(widget.title, Theme.of(context).textTheme.headline1,
maxWidth: _columnKey.currentContext.size.width)) {
maxWidth: maxWidth)) {
canExpand = true;
widget.shrinkTitle = getEclipsedText(
widget.title, Theme.of(context).textTheme.headline1,
maxWidth: _columnKey.currentContext.size.width);
maxWidth: maxWidth);
} else {
widget.shrinkTitle = widget.title;
}
Expand Down
110 changes: 51 additions & 59 deletions lib/notifications/notifications_table.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import 'dart:io';

import 'package:akar_icons_flutter/akar_icons_flutter.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:notifi/notifications/notification.dart';
import 'package:notifi/notifications/notifis.dart';
import 'package:notifi/screens/utils/loading_gif.dart';
import 'package:notifi/user.dart';
import 'package:notifi/utils/icons.dart';
import 'package:notifi/utils/pallete.dart';
import 'package:notifi/utils/utils.dart';
import 'package:provider/provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:toast/toast.dart';

class NotificationTable extends StatefulWidget {
const NotificationTable({Key key}) : super(key: key);
Expand Down Expand Up @@ -150,62 +149,53 @@ class NotificationTableState extends State<NotificationTable>
));

// slide actions
List<Widget> actions = <Widget>[
IconSlideAction(
caption: 'Title',
color: MyColour.transparent,
List<SlidableAction> actions = <SlidableAction>[
SlidableAction(
label: 'Title',
backgroundColor: MyColour.transparent,
foregroundColor: MyColour.darkGrey,
icon: Akaricons.copy,
onTap: () async {
icon: AkarIcons.copy,
onPressed: (_) async {
await copyText(notification.title, context);
},
),
IconSlideAction(
caption: 'Message',
color: MyColour.transparent,
SlidableAction(
label: 'Message',
backgroundColor: MyColour.transparent,
foregroundColor: MyColour.darkGrey,
icon: Akaricons.copy,
onTap: () async {
icon: AkarIcons.copy,
onPressed: (_) async {
await copyText(notification.message, context);
},
),
];

if (Platform.isIOS || Platform.isAndroid) {
actions = <Widget>[
IconSlideAction(
caption: 'Read',
color: MyColour.transparent,
foregroundColor: MyColour.grey,
icon: Akaricons.check,
onTap: () {
Provider.of<Notifications>(context, listen: false)
.toggleRead(index);
},
),
actions = <SlidableAction>[
SlidableAction(
backgroundColor: MyColour.transparent,
foregroundColor: MyColour.grey,
icon: AkarIcons.check,
label: 'Read',
onPressed: (_) {
Provider.of<Notifications>(context, listen: false)
.toggleRead(index);
}),
];

if (notification.link != '') {
actions.add(IconSlideAction(
caption: 'Link',
color: MyColour.transparent,
foregroundColor: MyColour.grey,
iconWidget: InkWell(
onTap: () async {
await openUrl(notification.link);
setState(() {
Provider.of<Notifications>(context, listen: false)
.markRead(notification.index, isRead: true);
});
},
onLongPress: () {
Toast.show(notification.link, context, gravity: Toast.CENTER);
},
child: Icon(
Akaricons.link,
color: MyColour.grey,
)),
));
actions.add(SlidableAction(
backgroundColor: MyColour.transparent,
foregroundColor: MyColour.grey,
icon: AkarIcons.link_chain,
label: 'Link',
onPressed: (_) async {
await openUrl(notification.link);
setState(() {
Provider.of<Notifications>(context, listen: false)
.markRead(notification.index, isRead: true);
});
}));
}
}

Expand All @@ -217,21 +207,23 @@ class NotificationTableState extends State<NotificationTable>
curve: Curves.easeIn,
child: Slidable(
key: Key(notification.id.toString()),
movementDuration: const Duration(milliseconds: 250),
actionPane: const SlidableDrawerActionPane(),
actionExtentRatio: 0.15,
actions: actions,
secondaryActions: <Widget>[
IconSlideAction(
color: MyColour.transparent,
foregroundColor: MyColour.grey,
icon: Akaricons.cross,
onTap: () {
Provider.of<Notifications>(context, listen: false)
.delete(index);
},
),
],
startActionPane:
ActionPane(motion: ScrollMotion(), children: actions),
endActionPane: ActionPane(
extentRatio: 0.25,
motion: ScrollMotion(),
children: <SlidableAction>[
SlidableAction(
backgroundColor: MyColour.transparent,
foregroundColor: MyColour.grey,
icon: AkarIcons.cross,
onPressed: (_) {
Provider.of<Notifications>(context, listen: false)
.delete(index);
},
),
],
),
child: notification)),
);
}
Expand Down
Loading

0 comments on commit e453fba

Please sign in to comment.