Skip to content

Commit

Permalink
New design and logic of notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
iiLubos committed Oct 18, 2023
1 parent 3e11a61 commit 9a38dbe
Show file tree
Hide file tree
Showing 12 changed files with 425 additions and 9 deletions.
4 changes: 4 additions & 0 deletions app/icons/Close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/icons/icons.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
<file>CloseButton.svg</file>
<file>UploadImage.svg</file>
<file>ReachedDataLimitImage.svg</file>
<file>Close.svg</file>
</qresource>
</RCC>
21 changes: 14 additions & 7 deletions app/qmlV2/component/MMInput.qml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ import "../Style.js" as Style
Item {
id: control

enum Type { Normal, Password, Search, Calendar, Scan, CopyButton }
enum Type { Normal, Password, Search, Calendar, Scan, CopyButton, SendButton }

property int type: MMInput.Type.Normal
property alias text: textField.text
property alias placeholderText: textField.placeholderText
property string warningMsg
property string errorMsg

signal sendButtonClicked

width: 280 * __dp
height: rect.height + messageItem.height

Expand Down Expand Up @@ -120,7 +122,7 @@ Item {
height: rect.height
visible: control.type === MMInput.Type.Password ||
control.type === MMInput.Type.Scan ||
((control.type !== MMInput.Type.CopyButton) && textField.activeFocus && textField.text.length>0)
((control.type !== MMInput.Type.CopyButton || control.type !== MMInput.Type.SendButton) && textField.activeFocus && textField.text.length>0)

MouseArea {
anchors.fill: parent
Expand All @@ -140,13 +142,13 @@ Item {
Button {
id: button

visible: control.type === MMInput.Type.CopyButton
visible: control.type === MMInput.Type.CopyButton || control.type === MMInput.Type.SendButton
anchors.verticalCenter: parent.verticalCenter

contentItem: Text {
anchors.centerIn: button
font: Qt.font(Style.t5)
text: qsTr("Copy")
text: control.type === MMInput.Type.CopyButton ? qsTr("Copy") : qsTr("Send")
leftPadding: 2 * __dp
rightPadding: 2 * __dp
topPadding: 2 * __dp
Expand All @@ -163,9 +165,14 @@ Item {
}

onClicked: {
textField.selectAll()
textField.copy()
textField.deselect()
if(control.type === MMInput.Type.CopyButton) {
textField.selectAll()
textField.copy()
textField.deselect()
}
else if(control.type === MMInput.Type.SendButton) {
sendButtonClicked()
}
}
}

Expand Down
91 changes: 91 additions & 0 deletions app/qmlV2/component/MMNotification.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

import QtQuick
import "../Style.js" as Style
import notificationType 1.0

Row {
id: notification

width: listView.width - 2 * Style.commonSpacing
height: Style.notificationHeight
anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined

readonly property int innerSpacing: 5 * __dp

Rectangle {
width: parent.width
height: parent.height
color: Style.forest
radius: Style.notificationRadius

Rectangle {
id: borderRect

anchors.centerIn: parent
width: parent.width - notification.innerSpacing
height: parent.height - notification.innerSpacing
radius: Style.notificationRadius
color: Style.transparent
border.width: __dp
border.color: {
switch( type ) {
case NotificationType.Information: return Style.sky
case NotificationType.Warning: return Style.warning
case NotificationType.Error: return Style.negative
default: return Style.positive
}
}
}

Rectangle {
id: icon

anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: Style.commonSpacing
width: 18 * __dp
height: 18 * __dp
color: borderRect.border.color
radius: width/2
}

Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: icon.right
width: parent.width - 3 * Style.commonSpacing - closeButton.width - icon.width
text: message
color: Style.white
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
leftPadding: Style.commonSpacing - notification.innerSpacing
font: Qt.font(Style.t3)
clip: true
}

Image {
id: closeButton

anchors.right: parent.right
anchors.rightMargin: Style.commonSpacing
anchors.verticalCenter: parent.verticalCenter
scale: maRemove.containsMouse ? 1.2 : 1
source: Style.closeIcon

MouseArea {
id: maRemove

anchors.fill: parent
hoverEnabled: true
onClicked: notificationModel.remove(id)
}
}
}
}
54 changes: 54 additions & 0 deletions app/qmlV2/component/MMNotificationView.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

import QtQuick
import "../Style.js" as Style

Item {
id: control

anchors.top: parent.top
anchors.topMargin: Style.commonSpacing
width: parent.width
height: parent.height

// just for information - will be removed in release version
Rectangle {
anchors.bottom: parent.bottom
width: control.width
height: 20
color: Style.white

Text {
text: listView.count
anchors.centerIn: parent
color: Style.forest
}
}

ListView {
id: listView

anchors.top: parent.top
width: parent.width
height: Style.notificationHeight * listView.count + spacing * (listView.count - 1)
spacing: Style.notificationSpace
clip: true
model: notificationModel
delegate: MMNotification {

}

add: Transition {
NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 200 }
NumberAnimation { property: "scale"; easing.type: Easing.OutCubic; from: 0; to: 1.0; duration: 200 }
}

}
}
4 changes: 2 additions & 2 deletions gallery/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ find_package(
qt_standard_project_setup()
qt_policy(SET QTP0001 NEW)

set(GALLERY_HDRS helper.h)
set(GALLERY_HDRS helper.h notificationmodel.h)

set(GALLERY_SRCS helper.cpp)
set(GALLERY_SRCS helper.cpp notificationmodel.cpp)

if (IOS OR ANDROID)
add_compile_definitions(MOBILE_OS)
Expand Down
4 changes: 4 additions & 0 deletions gallery/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "helper.h"
#include <QFont>
#include <QFontDatabase>
#include "notificationmodel.h"

int main( int argc, char *argv[] )
{
Expand All @@ -30,6 +31,9 @@ int main( int argc, char *argv[] )
engine.rootContext()->setContextProperty( "_hotReload", &hotReload );
#endif

NotificationModel notificationModel;
engine.rootContext()->setContextProperty("notificationModel", &notificationModel);

// path to local wrapper pages
engine.rootContext()->setContextProperty( "_qmlWrapperPath", QGuiApplication::applicationDirPath() + "/HotReload/qml/pages/" );
engine.rootContext()->setContextProperty( "__dp", Helper::calculateDpRatio() );
Expand Down
108 changes: 108 additions & 0 deletions gallery/notificationmodel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "notificationmodel.h"
#include <QQmlEngine>

Notification::Notification(uint id, const QString &message, uint interval, NotificationType::MessageType type = NotificationType::Information)
{
mId = id;
mMessage = message;
mInterval = interval;
mType = type;
}

NotificationModel::NotificationModel(QObject *parent) : QAbstractListModel{parent}
{
qmlRegisterUncreatableType<NotificationType>("notificationType", 1, 0, "NotificationType", "Not creatable as it is an enum type");

mTimer = new QTimer(this);
connect(mTimer, &QTimer::timeout, this, &NotificationModel::timerFired);
mTimer->start(1000);

// Initial data
mNotifications << Notification{ nextId(), "Ahoj", 10, NotificationType::Information };
mNotifications << Notification{ nextId(), "Hello all", 5, NotificationType::Information };
}

NotificationModel::~NotificationModel()
{
mTimer->stop();
delete mTimer;
}

QHash<int, QByteArray> NotificationModel::roleNames() const
{
return {
{ IdRole, "id" },
{ MessageRole, "message" },
{ TypeRole, "type" }
};
}

int NotificationModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return mNotifications.size();
}

QVariant NotificationModel::data(const QModelIndex &index, int role) const
{
if (!hasIndex(index.row(), index.column(), index.parent()))
return {};

Notification notification = mNotifications.at(index.row());
if (role == IdRole) return notification.id();
if (role == MessageRole) return notification.message();
if (role == TypeRole) return notification.type();

return {};
}

// remove item by message
void NotificationModel::remove(uint id)
{
for(int i=0; i<mNotifications.count(); i++) {
if(mNotifications[i].id() == id) {
beginRemoveRows(QModelIndex(), i, i);
mNotifications.removeAt(i);
endRemoveRows();

emit dataChanged(createIndex(0, 0), createIndex(rowCount(), 0)); // refresh whole model
emit rowCountChanged();
return;
}
}
}

// add new unique message with interval
void NotificationModel::add(const QString &message, uint interval, NotificationType::MessageType type = NotificationType::Information)
{
for(Notification &notification : mNotifications) {
if(notification.message() == message)
return;
}

beginInsertRows(QModelIndex(), rowCount(), rowCount());
mNotifications << Notification{ nextId(), message, interval, type };
endInsertRows();

emit rowCountChanged();
}

// check for auto removing notification
void NotificationModel::timerFired()
{
for(Notification &notification : mNotifications) {
if(notification.canBeRemoved())
remove(notification.id());
}
}


Loading

1 comment on commit 9a38dbe

@inputapp-bot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS - version 23.10.470411 just submitted!

Please sign in to comment.