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

Develop #234

Merged
merged 6 commits into from
Apr 2, 2022
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
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