4 Commits

Author SHA1 Message Date
693d2ad79e Improve release script 2025-11-11 14:51:06 +01:00
f19e8950e8 Fix confusion in AppSettings::load() 2025-11-11 14:38:25 +01:00
64d0541dc6 Add appstore links [skip-tests]
All checks were successful
Build Docker and Deploy / Run Unit-Tests (push) Has been skipped
Build Docker and Deploy / Build Docker Container (push) Successful in 43s
Build Docker and Deploy / Deploy to Server (push) Successful in 8s
2025-11-10 15:20:17 +01:00
dfb4d9d9e5 add privacy-policy [skip-tests]
All checks were successful
Build Docker and Deploy / Run Unit-Tests (push) Has been skipped
Build Docker and Deploy / Build Docker Container (push) Successful in 1m9s
Build Docker and Deploy / Deploy to Server (push) Successful in 8s
2025-11-10 15:13:28 +01:00
9 changed files with 133 additions and 46 deletions

View File

@@ -30,25 +30,7 @@ install-release: java gen
flutter run --release -d 35221JEHN07157 flutter run --release -d 35221JEHN07157
release: java gen release: java gen
flutter build apk --release @_utils/release.sh
cp build/app/outputs/flutter-apk/app-release.apk "_releases/v$(VERS).apk"
@echo ""
@echo "--> copied APK to _releases ( Version: $(VERS) )"
@echo ""
flutter build appbundle --release
cp build/app/outputs/bundle/release/app-release.aab "_releases/v$(VERS).aab"
cd "build/app/intermediates/merged_native_libs/release/out/lib" && zip -r "../../../../../../../_releases/v$(VERS).symbols.zip" .
@echo ""
@echo "--> copied AAB to _releases ( Version: $(VERS) )"
@echo ""
flutter build linux --release
tar -czf "_releases/v$(VERS).tar.gz" -C build/linux/x64/release/bundle .
@echo ""
@echo "--> copied linux-binary to _releases ( Version: $(VERS) )"
@echo ""
@echo "#=> file://$(shell pwd)/_releases"
@echo ""
@echo "Done."
test: test:
dart analyze dart analyze
@@ -63,7 +45,6 @@ gen: java
# run `make run` in another terminal (or another variant of flutter run) # run `make run` in another terminal (or another variant of flutter run)
autoreload: autoreload:
@
@_utils/autoreload.sh @_utils/autoreload.sh
icons: icons:

48
flutter/_utils/release.sh Executable file
View File

@@ -0,0 +1,48 @@
#!/bin/bash
if [[ -d ".git" ]]; then
echo "Must be called in project root"
exit 1
fi
VERS="$(cat pubspec.yaml | grep -oP '(?<=version: ).*' | sed 's/[\s]*//' | tr -d '\n' | tr -d '')"
VERS_BY_SPEC="$( echo -n "$VERS" | awk -F'+' '{print "v"$1}' )"
VERS_BY_TAG="$(git describe --abbrev=0 --tags)"
if [[ "$VERS_BY_TAG" != "$VERS_BY_SPEC" ]]; then
echo "Version in pubspec.yaml ($VERS_BY_SPEC) does not match latest git tag ($VERS_BY_TAG)"
exit 1
fi
echo ""
echo "(!) Make sure you've updated version-number in pubspec.yaml (current = ${VERS}) !"
echo 'Confirmed' && read -r
echo ""
flutter build apk --release
cp build/app/outputs/flutter-apk/app-release.apk "_releases/v${VERS}.apk"
echo ""
echo "--> copied APK to _releases ( Version: ${VERS} )"
echo ""
flutter build appbundle --release
cp build/app/outputs/bundle/release/app-release.aab "_releases/v${VERS}.aab"
cd "build/app/intermediates/merged_native_libs/release/out/lib" && zip -r "../../../../../../../_releases/v${VERS}.symbols.zip" .
echo ""
echo "--> copied AAB to _releases ( Version: ${VERS} )"
echo ""
flutter build linux --release
tar -czf "_releases/v${VERS}.tar.gz" -C build/linux/x64/release/bundle .
echo ""
echo "--> copied linux-binary to _releases ( Version: ${VERS} )"
echo ""
echo "#=> file://$(pwd)/_releases"
echo ""
echo "Done."

View File

@@ -83,7 +83,7 @@ class AppSettings extends ChangeNotifier {
dateFormat = AppSettingsDateFormat.ISO; dateFormat = AppSettingsDateFormat.ISO;
messagePreviewLength = 3; messagePreviewLength = 3;
showInfoAlerts = true; showInfoAlerts = true;
showExtendedAttributes = true; showExtendedAttributes = false;
notification0 = AppNotificationSettings(); notification0 = AppNotificationSettings();
notification1 = AppNotificationSettings(); notification1 = AppNotificationSettings();
@@ -102,7 +102,7 @@ class AppSettings extends ChangeNotifier {
dateFormat = AppSettingsDateFormat.parse(Globals().sharedPrefs.getString('settings.dateFormat')) ?? dateFormat; dateFormat = AppSettingsDateFormat.parse(Globals().sharedPrefs.getString('settings.dateFormat')) ?? dateFormat;
messagePreviewLength = Globals().sharedPrefs.getInt('settings.messagePreviewLength') ?? messagePreviewLength; messagePreviewLength = Globals().sharedPrefs.getInt('settings.messagePreviewLength') ?? messagePreviewLength;
showInfoAlerts = Globals().sharedPrefs.getBool('settings.showInfoAlerts') ?? showInfoAlerts; showInfoAlerts = Globals().sharedPrefs.getBool('settings.showInfoAlerts') ?? showInfoAlerts;
showInfoAlerts = Globals().sharedPrefs.getBool('settings.showExtendedAttributes') ?? showExtendedAttributes; showExtendedAttributes = Globals().sharedPrefs.getBool('settings.showExtendedAttributes') ?? showExtendedAttributes;
notification0 = AppNotificationSettings.load(Globals().sharedPrefs, 'settings.notification0'); notification0 = AppNotificationSettings.load(Globals().sharedPrefs, 'settings.notification0');
notification1 = AppNotificationSettings.load(Globals().sharedPrefs, 'settings.notification1'); notification1 = AppNotificationSettings.load(Globals().sharedPrefs, 'settings.notification1');
@@ -160,14 +160,7 @@ class AppSettings extends ChangeNotifier {
class AppNotificationSettings { class AppNotificationSettings {
// Immutable // Immutable
AppNotificationSettings({ AppNotificationSettings({this.enableLights = false, this.enableVibration = true, this.playSound = true, this.sound = null, this.silent = false, this.timeoutAfter = null});
this.enableLights = false,
this.enableVibration = true,
this.playSound = true,
this.sound = null,
this.silent = false,
this.timeoutAfter = null,
});
final bool enableLights; final bool enableLights;
final bool enableVibration; final bool enableVibration;
@@ -206,14 +199,7 @@ class AppNotificationSettings {
final silent = prefs.getBool('${prefix}.silent') ?? def.silent; final silent = prefs.getBool('${prefix}.silent') ?? def.silent;
final timeoutAfter = _decode(prefs.getString('${prefix}.timeoutAfter'), def.timeoutAfter); final timeoutAfter = _decode(prefs.getString('${prefix}.timeoutAfter'), def.timeoutAfter);
return AppNotificationSettings( return AppNotificationSettings(enableLights: enableLights, enableVibration: enableVibration, playSound: playSound, sound: sound, silent: silent, timeoutAfter: timeoutAfter);
enableLights: enableLights,
enableVibration: enableVibration,
playSound: playSound,
sound: sound,
silent: silent,
timeoutAfter: timeoutAfter,
);
} }
} }

View File

@@ -2,7 +2,7 @@ name: simplecloudnotifier
description: "Receive push messages" description: "Receive push messages"
publish_to: 'none' publish_to: 'none'
version: 2.1.0+502 version: 2.1.0+509
environment: environment:
sdk: '>=3.9.0 <4.0.0' sdk: '>=3.9.0 <4.0.0'

View File

@@ -1,18 +1,19 @@
package handler package handler
import ( import (
"errors"
"net/http"
"regexp"
"strings"
"blackforestbytes.com/simplecloudnotifier/api/ginresp" "blackforestbytes.com/simplecloudnotifier/api/ginresp"
"blackforestbytes.com/simplecloudnotifier/logic" "blackforestbytes.com/simplecloudnotifier/logic"
"blackforestbytes.com/simplecloudnotifier/models" "blackforestbytes.com/simplecloudnotifier/models"
"blackforestbytes.com/simplecloudnotifier/website" "blackforestbytes.com/simplecloudnotifier/website"
"errors"
"git.blackforestbytes.com/BlackForestBytes/goext/ginext" "git.blackforestbytes.com/BlackForestBytes/goext/ginext"
"git.blackforestbytes.com/BlackForestBytes/goext/rext" "git.blackforestbytes.com/BlackForestBytes/goext/rext"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"net/http"
"regexp"
"strings"
) )
type WebsiteHandler struct { type WebsiteHandler struct {
@@ -77,6 +78,18 @@ func (h WebsiteHandler) MessageSent(pctx ginext.PreContext) ginext.HTTPResponse
}) })
} }
func (h WebsiteHandler) PrivacyPolicy(pctx ginext.PreContext) ginext.HTTPResponse {
ctx, g, errResp := pctx.Start()
if errResp != nil {
return *errResp
}
defer ctx.Cancel()
return h.app.DoRequest(ctx, g, models.TLockNone, func(ctx *logic.AppContext, finishSuccess func(r ginext.HTTPResponse) ginext.HTTPResponse) ginext.HTTPResponse {
return h.serveAsset(g, "privacy_policy.html", true)
})
}
func (h WebsiteHandler) FaviconIco(pctx ginext.PreContext) ginext.HTTPResponse { func (h WebsiteHandler) FaviconIco(pctx ginext.PreContext) ginext.HTTPResponse {
ctx, g, errResp := pctx.Start() ctx, g, errResp := pctx.Start()
if errResp != nil { if errResp != nil {

View File

@@ -1,11 +1,12 @@
package api package api
import ( import (
"errors"
"blackforestbytes.com/simplecloudnotifier/api/handler" "blackforestbytes.com/simplecloudnotifier/api/handler"
"blackforestbytes.com/simplecloudnotifier/logic" "blackforestbytes.com/simplecloudnotifier/logic"
"blackforestbytes.com/simplecloudnotifier/models" "blackforestbytes.com/simplecloudnotifier/models"
"blackforestbytes.com/simplecloudnotifier/swagger" "blackforestbytes.com/simplecloudnotifier/swagger"
"errors"
"git.blackforestbytes.com/BlackForestBytes/goext/ginext" "git.blackforestbytes.com/BlackForestBytes/goext/ginext"
"github.com/gin-gonic/gin/binding" "github.com/gin-gonic/gin/binding"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
@@ -98,6 +99,10 @@ func (r *Router) Init(e *ginext.GinWrapper) error {
frontend.GET("/message_sent.php").Handle(r.websiteHandler.MessageSent) frontend.GET("/message_sent.php").Handle(r.websiteHandler.MessageSent)
frontend.GET("/message_sent.html").Handle(r.websiteHandler.MessageSent) frontend.GET("/message_sent.html").Handle(r.websiteHandler.MessageSent)
frontend.GET("/privacy_policy").Handle(r.websiteHandler.PrivacyPolicy)
frontend.GET("/privacy_policy.php").Handle(r.websiteHandler.PrivacyPolicy)
frontend.GET("/privacy_policy.html").Handle(r.websiteHandler.PrivacyPolicy)
frontend.GET("/favicon.ico").Handle(r.websiteHandler.FaviconIco) frontend.GET("/favicon.ico").Handle(r.websiteHandler.FaviconIco)
frontend.GET("/favicon.png").Handle(r.websiteHandler.FaviconPNG) frontend.GET("/favicon.png").Handle(r.websiteHandler.FaviconPNG)

View File

@@ -15,7 +15,7 @@
<form id="mainpnl"> <form id="mainpnl">
<a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a> <a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a>
<a tabindex="-1" href="#" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a> <a tabindex="-1" href="https://apps.apple.com/us/app/simplecloudnotifier/id6455594868" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a>
<a tabindex="-1" href="/api" class="button bordered edge-btn" id="tr_link">API</a> <a tabindex="-1" href="/api" class="button bordered edge-btn" id="tr_link">API</a>

View File

@@ -15,7 +15,7 @@
<div id="mainpnl"> <div id="mainpnl">
<a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a> <a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a>
<a tabindex="-1" href="#" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a> <a tabindex="-1" href="https://apps.apple.com/us/app/simplecloudnotifier/id6455594868" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a>
<a tabindex="-1" href="/" class="button bordered edge-btn" id="tr_link">Send</a> <a tabindex="-1" href="/" class="button bordered edge-btn" id="tr_link">Send</a>

View File

@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template|header.[theme].html}}
</head>
<body>
<div id="copyinfo">
<a tabindex="-1" href="https://www.blackforestbytes.com">&#169; blackforestbytes</a>
<a tabindex="-1" href="https://www.mikescher.com">made by Mike Schw&ouml;rer</a>
</div>
{{template|theme_switch.[theme].html}}
<div id="mainpnl">
<strong>Privacy Policy</strong>
<p>This privacy policy applies to the SimpleCloudNotifier app (hereby referred to as "Application") for mobile devices that was created by blackforestbytes GmbH (hereby referred to as "Service Provider") as a Free service. This service is intended for use "AS IS".</p>
<br>
<strong>What information does the Application obtain and how is it used?</strong>
<p>The Application does not obtain any information when you download and use it. Registration is not required to use the Application.</p>
<br>
<strong>Does the Application collect precise real time location information of the device?</strong>
<p>This Application does not collect precise information about the location of your mobile device.</p>
<br>
<strong>Do third parties see and/or have access to information obtained by the Application?</strong>
<p>Since the Application does not collect any information, no data is shared with third parties.</p>
<br>
<strong>What are my opt-out rights?</strong>
<p>You can stop all collection of information by the Application easily by uninstalling it. You may use the standard uninstall processes as may be available as part of your mobile device or via the mobile application marketplace or network.</p>
<br>
<strong>Children</strong>
<p>The Application is not used to knowingly solicit data from or market to children under the age of 13.</p>
<br>
<p>The Service Provider does not knowingly collect personally identifiable information from children. The Service Provider encourages all children to never submit any personally identifiable information through the Application and/or Services. The Service Provider encourage parents and legal guardians to monitor their children's Internet usage and to help enforce this Policy by instructing their children never to provide personally identifiable information through the Application and/or Services without their permission. If you have reason to believe that a child has provided personally identifiable information to the Service Provider through the Application and/or Services, please contact the Service Provider (playstore_scn@blackforestbytes.de) so that they will be able to take the necessary actions. You must also be at least 16 years of age to consent to the processing of your personally identifiable information in your country (in some countries we may allow your parent or guardian to do so on your behalf).</p>
<br>
<strong>Security</strong>
<p>The Service Provider is concerned about safeguarding the confidentiality of your information. However, since the Application does not collect any information, there is no risk of your data being accessed by unauthorized individuals.</p>
<br>
<strong>Changes</strong>
<p>This Privacy Policy may be updated from time to time for any reason. The Service Provider will notify you of any changes to their Privacy Policy by updating this page with the new Privacy Policy. You are advised to consult this Privacy Policy regularly for any changes, as continued use is deemed approval of all changes.</p>
<br>
<p>This privacy policy is effective as of 2025-11-10</p>
<br>
<strong>Your Consent</strong>
<p>By using the Application, you are consenting to the processing of your information as set forth in this Privacy Policy now and as amended by the Service Provider.</p>
<br><strong>Contact Us</strong>
<p>If you have any questions regarding privacy while using the Application, or have questions about the practices, please contact the Service Provider via email at playstore_scn@blackforestbytes.de.</p>
<hr>
<p>This privacy policy page was generated by <a href="https://app-privacy-policy-generator.nisrulz.com/" target="_blank" rel="noopener noreferrer">App Privacy Policy Generator</a></p>
</div>
</body>
</html>