File indexing completed on 2025-02-02 05:02:32

0001 /*
0002     SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "notificationhelper.h"
0008 #include "logging.h"
0009 
0010 #include <KPublicTransport/Stopover>
0011 
0012 #include <KLocalizedString>
0013 
0014 using namespace KPublicTransport;
0015 
0016 static bool isSignificantDelayChange(int oldDelay, int newDely)
0017 {
0018     // TODO we could do this relatively: 60 -> 62 matters less than 0 -> 2, for example
0019     return std::abs(oldDelay - newDely) > 2;
0020 }
0021 
0022 bool NotificationHelper::shouldNotify(const Stopover &oldStop, const Stopover &newStop, LiveData::Type context)
0023 {
0024     // disruption state changed
0025     if (oldStop.disruptionEffect() != newStop.disruptionEffect()) {
0026         return true;
0027     }
0028 
0029     // platform changed
0030     if ((newStop.hasExpectedPlatform() && oldStop.hasExpectedPlatform() && oldStop.expectedPlatform() != newStop.expectedPlatform())
0031         || (!oldStop.hasExpectedPlatform() && newStop.platformChanged()))
0032     {
0033         return true;
0034     }
0035 
0036     // delay changed
0037     if (context == LiveData::Departure && newStop.hasExpectedDepartureTime() && isSignificantDelayChange(oldStop.departureDelay(), newStop.departureDelay())) {
0038         return true;
0039     }
0040     if (context == LiveData::Arrival && newStop.hasExpectedArrivalTime() && isSignificantDelayChange(oldStop.arrivalDelay(), newStop.arrivalDelay())) {
0041         return true;
0042     }
0043 
0044     return false;
0045 }
0046 
0047 static QString lineName(const LiveData &data)
0048 {
0049     if (!data.departure.route().line().name().isEmpty()) {
0050         return data.departure.route().line().name();
0051     }
0052     if (!data.arrival.route().line().name().isEmpty()) {
0053         return data.arrival.route().line().name();
0054     }
0055     qCWarning(Log) << "Trying to create notification but no line name available!?";
0056     return {};
0057 }
0058 
0059 QString NotificationHelper::title(const LiveData &data)
0060 {
0061     if (data.departure.disruptionEffect() != Disruption::NormalService || data.arrival.disruptionEffect() != Disruption::NormalService) {
0062         return i18n("Disruption on %1", lineName(data));
0063     }
0064 
0065     const auto platformChange = data.departure.platformChanged() || data.arrival.platformChanged();
0066     const auto oneDelay = data.departure.departureDelay() != 0 || data.arrival.arrivalDelay() > 0;
0067     const auto multiDelay = data.departure.departureDelay() != 0 && data.arrival.arrivalDelay() > 0;
0068 
0069     if (platformChange && oneDelay) {
0070         return i18n("Changes on %1", lineName(data));
0071     }
0072 
0073     if (multiDelay) {
0074         return i18n("Delays on %1", lineName(data));
0075     }
0076     if (data.departure.departureDelay() > 0) {
0077         return i18n("Delayed departure on %1", lineName(data));
0078     }
0079     if (data.departure.departureDelay() < 0) {
0080         return i18n("Earlier departure on %1", lineName(data));
0081     }
0082     if (data.arrival.arrivalDelay() > 0) {
0083         return i18n("Delayed arrival on %1", lineName(data));
0084     }
0085 
0086     if (platformChange) {
0087         return i18n("Platform change on %1", lineName(data));
0088     }
0089 
0090     return {};
0091 }
0092 
0093 QString NotificationHelper::message(const LiveData &data)
0094 {
0095     QStringList msgs;
0096     if (data.departure.disruptionEffect() == Disruption::NoService) {
0097         msgs.push_back(i18nc("a train/bus journey canceled by its operator", "Trip has been canceled."));
0098     } else if (data.arrival.disruptionEffect() == Disruption::NoService) {
0099         msgs.push_back(i18nc("a train/bus journey canceled by its operator", "Arrival has been canceled."));
0100     }
0101 
0102     if (data.departure.departureDelay() > 0) {
0103         msgs.push_back(i18n("New departure time is: %1 (+%2)", QLocale().toString(data.departure.expectedDepartureTime().time()), data.departure.departureDelay()));
0104     } else if (data.departure.departureDelay() < 0) {
0105         msgs.push_back(i18n("New departure time is: %1 (%2)", QLocale().toString(data.departure.expectedDepartureTime().time()), data.departure.departureDelay()));
0106     }
0107 
0108     if (data.arrival.arrivalDelay() > 0) {
0109         msgs.push_back(i18n("New arrival time is: %1 (+%2)", QLocale().toString(data.arrival.expectedArrivalTime().time()), data.arrival.arrivalDelay()));
0110     }
0111 
0112     if (data.departure.platformChanged()) {
0113         msgs.push_back(i18n("New departure platform is: %1", data.departure.expectedPlatform()));
0114     }
0115     if (data.arrival.platformChanged()) {
0116         msgs.push_back(i18n("New arrival platform is: %1", data.arrival.expectedPlatform()));
0117     }
0118 
0119     return msgs.join(QLatin1Char('\n'));
0120 }