From 7be46f60bb009d7940f749cdbd4126dd4dfd4217 Mon Sep 17 00:00:00 2001 From: silas Date: Wed, 10 Oct 2018 19:13:23 +0200 Subject: [PATCH] Logging von Sharing und Installing --- orga/test.sql | 2 +- public/js/app.js | 87 +++++++++++++------ public/js/lang/de.json | 2 +- src/js/init.js | 8 +- src/js/lib/pwa-assets.js | 52 ++++++----- src/js/lib/pwa-lib.js | 32 ++++++- .../js/Fragment/WordRotatorSettingFragment.js | 3 + .../Application/pwa/translations/de.json | 2 +- 8 files changed, 131 insertions(+), 57 deletions(-) diff --git a/orga/test.sql b/orga/test.sql index fa51aa3..c8a06ea 100644 --- a/orga/test.sql +++ b/orga/test.sql @@ -76,7 +76,7 @@ INSERT INTO `Level` (`id`, `words`, `positions`, `renderer`, `lastUpdated`, `lan (15, '["ARCHIV","CHARME"]', '[1,1,3]', 20, '2018-07-14 17:01:18', 1, 0, 2), (26, '["BODENSEE","ALARMRUF"]', '[3,2,0,3]', 40, '2018-07-14 17:01:18', 1, 0, 40), (217, '["ZEITSTRAFE","HOCHSAISON"]', '[1,0,3,3,1]', 60, '2018-07-14 17:01:18', 1, 0, 60), -(220, '["FEINGUSS","R\\u00dcCKFALL","PHYSIKER","RESIDENZ","BERATUNG","HERZLAND"]', '[2,0,0,1,2,2,3,3,2,1,1,2,0,0]', 100, '2018-07-14 17:01:18', 1, 0, 100), +(220, '["FEINGUSS","R\\u00dcCKFALL","PHYSIKER","RESIDENZ","BERATUNG","KOCHTOPF"]', '[2,0,0,1,2,2,3,3,2,1,1,2,0,0]', 100, '2018-07-14 17:01:18', 1, 0, 100), (24, '["BETONUNG","ANBETUNG","ALLERGIE","BAUMHAUS"]', '[0,3,1,1,3,1,2,0,0,0]', 120, '2018-07-14 17:01:18', 1, 0, 120), (62, '["FEHLPROGNOSE","GEISTESKRAFT","ARBEITSPAUSE","BEREITSCHAFT","MOSAIKARBEIT","INFRAROTFILM"]', '[0,3,0,1,0,3,2,3,1,2,3,1,2,2,0,2,3,0,2,1,1]', 140, '2018-07-14 17:01:18', 1, 0, 140), (260, '["SCHREIBTISCH","URHEBERRECHT","PFLANZENKOST","OPERNKONZERT"]', '[1,3,2,1,3,0,1,2,3,0,2,0,1,0,0]', 160, '2018-07-14 17:01:18', 1, 0, 160), diff --git a/public/js/app.js b/public/js/app.js index ef4b616..eebee69 100755 --- a/public/js/app.js +++ b/public/js/app.js @@ -2936,7 +2936,7 @@ class ShareButton { this._deviceType = deviceType; this._icon = icon; this._callback = callback; - console.log("shouldLoad", Helper.nonNull(shouldLoadImg, false), shouldLoadImg); + if (Helper.nonNull(shouldLoadImg, false)){ this._icon = ViewInflater.inflate(this._icon); } @@ -2963,6 +2963,34 @@ ShareButton.TYPE_MOBILE_LEFTOVER = 4; ShareButton.TYPE_MOBILE = ShareButton.TYPE_MOBILE_APPLE+ShareButton.TYPE_MOBILE_LEFTOVER; ShareButton.TYPE_ALL = ShareButton.TYPE_DESKTOP+ShareButton.TYPE_MOBILE; +class MultipleShareButton extends ShareButton{ + constructor(deviceType, icon, callbacks, shouldLoadImg) + { + console.log(Array.isArray(deviceType), deviceType[0] instanceof ShareButton); + if (Array.isArray(deviceType) && deviceType[0] instanceof ShareButton){ + let btn = deviceType[0]; + deviceType = btn._deviceType; + icon = btn._icon; + callbacks = deviceType; + shouldLoadImg = Helper.nonNull(shouldLoadImg, icon); + } + + super(deviceType, icon, function (link, element, event) { + if (!Array.isArray(callbacks)){ + callbacks = [callbacks]; + } + for (let i = 0; i < callbacks.length; i++) { + if (callbacks[i] instanceof ShareButton){ + callbacks[i].getCallback()(link, element, event); + } + else { + callbacks[i](link, element, event); + } + } + }, shouldLoadImg); + } +} + class ShareManager { static init() { ShareManager.shareButtons = []; @@ -4677,16 +4705,13 @@ class Matomo { g.src = Matomo.TRACK_SITE + '/piwik.js'; s.appendChild(g); }); - // window.addEventListener('hashchange', () => { - // Matomo.update() - // }); } static update(title) { - if (Helper.nonNull(Matomo.currentUrl)){ + if (Helper.nonNull(Matomo.currentUrl)) { Matomo.push(['setReferrerUrl', Matomo.currentUrl]); } - Matomo.currentUrl = window.location.pathname+window.location.search; + Matomo.currentUrl = window.location.pathname + window.location.search; Matomo.push(['setCustomUrl', Matomo.currentUrl]); Matomo.push(['setDocumentTitle', title]); @@ -4712,17 +4737,10 @@ class Matomo { resolve(!this["isUserOptedOut"]()); }]); }); - // Matomo.isTrackingPromise = Matomo.query("isTracked") - // .then(xml => { - // let textContent = xml.firstChild.textContent; - // // localStorage.setItem(Matomo.LOCAL_STORAGE_KEY, textContent); - // return (textContent === "1") - // }); return Matomo.isTrackingPromise; } - static - async query(method) { + static async query(method) { return fetch(Matomo.TRACK_SITE + Matomo.BASE_PATH + method, { "mode": "cors", "credentials": "include", @@ -4733,11 +4751,10 @@ class Matomo { return Matomo.isTrackingPromise; } - static - async setTrack(shouldTrack) { + static async setTrack(shouldTrack) { Matomo.isTrackingPromise = Promise.resolve(shouldTrack); localStorage.setItem(Matomo.LOCAL_STORAGE_KEY, (shouldTrack === true) ? "1" : "0"); - // return await Matomo.query((shouldTrack) ? "doTrack" : "doIgnore"); + if (shouldTrack) { Matomo.push(["forgetUserOptOut"], true); } @@ -4746,16 +4763,24 @@ class Matomo { } } - static - async push(arr, force) { - // force = Helper.nonNull(force, false); + static async trackEvent(event, name, label, value){ + let ev = ["trackEvent", event, name]; + if (Helper.isNotNull(label)){ + ev.push(label); + } + if (Helper.isNotNull(value) && !isNaN(parseFloat(value)) && isFinite(value)){ + ev.push(value); + } + + return this.push(ev); + } + + static async push(arr, force) { if (!Array.isArray(arr)) { arr = [arr]; } - // if (force || await Matomo.getTrackingPromise()) { window["_paq"].push(arr); - // } } } @@ -4771,6 +4796,15 @@ InitPromise.addPromise(() => { Matomo.init(); }); +class MatomoShareButton extends MultipleShareButton{ + + constructor(baseButton, platform, shouldLoadImg) { + super([baseButton, (url) => { + Matomo.trackEvent("shared", url, platform); + }], shouldLoadImg); + } +} + class ScaleHelper { async scaleTo(scale, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animationDelay, addListener) { @@ -6848,6 +6882,9 @@ class WordRotatorSettingFragment extends LocalStorageSettingsFragment { installButton.classList.add("hidden"); InstallManager.prompt().then((e) => { console.log("clicked", e); + if (e["outcome"] === "accepted"){ + Matomo.trackEvent("installed", "installed"); + } }); }); installButton.classList.remove("hidden"); @@ -6887,9 +6924,9 @@ ThemeManager.addTheme(new Theme("green", "green")); ThemeManager.addTheme(new Theme("pink", "pink")); ThemeManager.addTheme(new Theme("dark", "dark")); -ShareManager.addShareButton(new WhatsappShareButton('img/whatsapp.svg', true)); -ShareManager.addShareButton(new SmsShareButton('img/sms.svg', true)); -ShareManager.addShareButton(new TelegramShareButton('img/telegram.svg', true)); +ShareManager.addShareButton(new MatomoShareButton(new WhatsappShareButton('img/whatsapp.svg'), "whatsapp", true)); +ShareManager.addShareButton(new MatomoShareButton(new SmsShareButton('img/sms.svg'), "sms", true)); +ShareManager.addShareButton(new MatomoShareButton(new TelegramShareButton('img/telegram.svg'), "telegram", true)); // ShareManager.addShareButton(new CopyShareButton('img/copy.svg')); let app = new App(); diff --git a/public/js/lang/de.json b/public/js/lang/de.json index 96c883a..016cabd 100755 --- a/public/js/lang/de.json +++ b/public/js/lang/de.json @@ -1 +1 @@ -{"won":"Gewonnen!","continue":"Weiter","help":"?","not-enough-coins":"Du hast zu wenig Münzen!","sync-error":"Es gab einen Fehler beim Aktualisieren der Level. Bitte stelle sicher, dass du eine aktive Internetverbindung hast und versuche es später erneut.","game-ended":"Oh nein!
Es sieht so aus, als ob du schon alle Level gespielt hast...
Schau später noch einmal rein, evtl gibt es dann neue Level.","play":"Spielen!","tutorial-step-1":"Klicke auf ein Feld, um dieses rotieren zu lassen!","tutorial-step-2":"Um zu gewinnen, drehe die Segmente so, dass du zwei Wörter lesen kannst.","tutorial-step-3":"Durch die Hilfe kannst du ein Segment lösen lassen. Die Hilfe kostet aber 25 Münzen. Probiere jetzt die Hilfe aus.","tutorial-step-4":"Große Segmente drehst du, indem du diese ziehst.","extra-coins-after-first-level":"Für das erste Level gibt es 50 extra Münzen!","dark":"Dunkel","theme":"Theme:","sound":"Sound:","music":"Musik:","credits":"Credits","privacy-policy":"Datenschutzbestimmungen","impressum":"Impressum","track":"Anonymisierte Nutzungsdaten senden:",">":">","choose-theme-dialog-title":"Theme auswählen:","install":"Installieren","share-dialog":"Teilen:","Sunday":"Sonntag","Monday":"Montag","Tuesday":"Dienstag","Wednesday":"Mittwoch","Thursday":"Donnerstag","Friday":"Freitag","Saturday":"Samstag","January":"Januar","February":"Februar","March":"März","April":"April","May":"Mai","June":"Juni","July":"Juli","August":"August","September":"September","October":"Oktober","November":"November","December":"Dezember","Sun":"So","Mon":"Mo","Tue":"Di","Wed":"Mi","Thu":"Do","Fri":"Fr","Sat":"Sa","Jan":"Jan","Feb":"Feb","Mar":"Mär","Apr":"Apr","Jun":"Jun","Jul":"Jul","Aug":"Aug","Sep":"Sep","Oct":"Okt","Nov":"Nov","Dec":"Dez","code-not-valid":"Der angegebebe Code ist nicht gültig!","code-activated":"Der Code wurde erfolgreich aktiviert!","current-lang":"DE","en":"Englisch","de":"Deutsch","black":"Schwarz","red":"Rot","blue":"Blau","green":"Grün","pink":"Rosa","cancel-button":"ABBRECHEN","confirm-button":"OK","we-use-cookie-hint":"Diese Seite nutzt Cookies. Durch das weitere Benutzen dieser Seite geben Sie uns das Recht Cookies so zu benutzen, wie es in unserer Datenschutzerklärung steht.","policy-heading":"Datenschutzerklärung","area-of-validity-heading":"Geltungsbereich","area-of-validity":"Diese Datenschutzerklärung klärt Nutzer über die Art, den Umfang und Zwecke der Erhebung und Verwendung personenbezogener Daten durch den verantwortlichen Anbieter Silas Günther, Langenbusch 263b - 42897 Remscheid, matrix[at]silas.link auf dieser Website (im folgenden \"Angebot\") auf.

Die rechtlichen Grundlagen des Datenschutzes finden sich im Bundesdatenschutzgesetz (BDSG) und dem Telemediengesetz (TMG).","logfiles-heading":"Zugriffsdaten / Server-Logfiles","logfiles":"Der Anbieter (beziehungsweise sein Webspace-Provider) erhebt Daten über jeden Zugriff auf das Angebot (so genannte Serverlogfiles). Zu den Zugriffsdaten gehören:

Name der abgerufenen Webseite, Datei, Datum und Uhrzeit des Abrufs, übertragene Datenmenge, Meldung über erfolgreichen Abruf, Browsertyp nebst Version, das Betriebssystem des Nutzers, Referrer URL (die zuvor besuchte Seite), IP-Adresse und der anfragende Provider.

Der Anbieter verwendet die Protokolldaten nur für statistische Auswertungen zum Zweck des Betriebs, der Sicherheit und der Optimierung des Angebotes. Der Anbieter behält sich jedoch vor, die Protokolldaten nachträglich zu überprüfen, wenn aufgrund konkreter Anhaltspunkte der berechtigte Verdacht einer rechtswidrigen Nutzung besteht.","contact-support-heading":"Kontaktaufnahme","contact-support":"Bei der Kontaktaufnahme mit dem Anbieter (zum Beispiel per Post oder E-Mail) werden die Angaben des Nutzers zwecks Bearbeitung der Anfrage sowie für den Fall, dass Anschlussfragen entstehen, gespeichert.","cookies-heading":"Cookies","cookies":"Cookies sind kleine Dateien, die es ermöglichen, auf dem Zugriffsgerät der Nutzer (PC, Smartphone o.ä.) spezifische, auf das Gerät bezogene Informationen zu speichern. Sie dienen zum einem der Benutzerfreundlichkeit von Webseiten und damit den Nutzern (z.B. Speicherung von Logindaten). Zum anderen dienen sie, um die statistische Daten der Webseitennutzung zu erfassen und sie zwecks Verbesserung des Angebotes analysieren zu können. Die Nutzer können auf den Einsatz der Cookies Einfluss nehmen. Die meisten Browser verfügen eine Option mit der das Speichern von Cookies eingeschränkt oder komplett verhindert wird. Allerdings wird darauf hingewiesen, dass die Nutzung und insbesondere der Nutzungskomfort ohne Cookies eingeschränkt werden.

Sie können viele Online-Anzeigen-Cookies von Unternehmen über die US-amerikanische Seite http://www.aboutads.info/choices/ oder die EU-Seite http://www.youronlinechoices.com/uk/your-ad-choices/ verwalten.","google-analytics-heading":"Google Analytics","google-analytics":"Dieses Angebot benutzt Google Analytics, einen Webanalysedienst der Google Inc. („Google“). Google Analytics verwendet sog. „Cookies“, Textdateien, die auf Computer der Nutzer gespeichert werden und die eine Analyse der Benutzung der Website durch sie ermöglichen. Die durch den Cookie erzeugten Informationen über Benutzung dieser Website durch die Nutzer werden in der Regel an einen Server von Google in den USA übertragen und dort gespeichert.

Im Falle der Aktivierung der IP-Anonymisierung auf dieser Webseite, wird die IP-Adresse der Nutzer von Google jedoch innerhalb von Mitgliedstaaten der Europäischen Union oder in anderen Vertragsstaaten des Abkommens über den Europäischen Wirtschaftsraum zuvor gekürzt. Nur in Ausnahmefällen wird die volle IP-Adresse an einen Server von Google in den USA übertragen und dort gekürzt. Die IP-Anonymisierung ist auf dieser Website aktiv. Im Auftrag des Betreibers dieser Website wird Google diese Informationen benutzen, um die Nutzung der Website durch die Nutzer auszuwerten, um Reports über die Websiteaktivitäten zusammenzustellen und um weitere mit der Websitenutzung und der Internetnutzung verbundene Dienstleistungen gegenüber dem Websitebetreiber zu erbringen.

Die im Rahmen von Google Analytics von Ihrem Browser übermittelte IP-Adresse wird nicht mit anderen Daten von Google zusammengeführt. Die Nutzer können die Speicherung der Cookies durch eine entsprechende Einstellung Ihrer Browser-Software verhindern; Dieses Angebot weist die Nutzer jedoch darauf hin, dass Sie in diesem Fall gegebenenfalls nicht sämtliche Funktionen dieser Website vollumfänglich werden nutzen können. Die Nutzer können darüber hinaus die Erfassung der durch das Cookie erzeugten und auf ihre Nutzung der Website bezogenen Daten (inkl. Ihrer IP-Adresse) an Google sowie die Verarbeitung dieser Daten durch Google verhindern, indem sie das unter dem folgenden Link verfügbare Browser-Plugin herunterladen und installieren: http://tools.google.com/dlpage/gaoptout?hl=de.

Weitere Informationen zur Datennutzung zu Werbezwecken durch Google, Einstellungs- und Widerspruchsmöglichkeiten erfahren Sie auf den Webseiten von Google:
https://www.google.com/intl/de/policies/privacy/partners/ („Datennutzung durch Google bei Ihrer Nutzung von Websites oder Apps unserer Partner“),
http://www.google.com/policies/technologies/ads („Datennutzung zu Werbezwecken“),
http://www.google.de/settings/ads („Informationen verwalten, die Google verwendet, um Ihnen Werbung einzublenden“) und
http://www.google.com/ads/preferences/ („Bestimmen Sie, welche Werbung Google Ihnen zeigt“).","edited-hint":"Der generierte Text wurde vom Webseiteninhaber angepasst.","generated-hint":"Erstellt mit Datenschutz-Generator.de von RA Dr. Thomas Schwenke","google-play-services-heading":"Google Play Dienste","google-play-services":"Features wie die Bestenliste und Erfolge benötigen einen Login bei Google Play. Hierfür wird die Identität benötigt, um die entsprechenden Punktzahlen und Erfolge an das jeweilige Google Play-Konto zu knüpfen. Alle anderen Features sind weiterhin auch ohne Login bei Google Play nutzbar. Außerdem kann sich jederzeit in den Einstellungen von Google Play abgemeldet werden.","settings":"Einstellungen","close":"Schließen","other-apps":"Andere Apps","optimistic-locking-dialog":"Deine Änderungen können nicht gespeichert werden! Ein anderer Benutzer hat die Daten bereits verändert. Bitte lade die Daten neu und speichere danach.","optimistic-locking-dialog-title":"Nicht gespeichert!","not-online":"Du bist nicht mit dem Internet verbunden. Bitte überprüfe deine Verbindung.","search":"Suchen...","site":"Seite","HTTP-Exception (403) Forbidden":"Nicht erlaubt!","login":"Login","login-email":"E-Mail","login-password":"Passwort","login-automated-login":"Automatischer Login","login-submit":"Login","logout":"Ausloggen","username-or-password-wrong":"Entweder der Username oder das Passwort stimmt nicht!","login-success":"Willkommen zurück!","logged-out-successfully":"Tschüss!","registration":"Registrieren","registration-username":"Username","registration-email":"E-Mail","registration-password1":"Passwort","registration-password2":"Passwort wiederholen","registration-submit":"Registrieren","registration-success":"Ein Registrierungscode wurde an Ihre E-Mailadresse gesendet.","not-allowed-title":"Nicht erlaubt!","not-allowed":"Du hast keine Berechtigung für diese Seite. Wenn das ein Fehler ist, wende dich bitte an einen Admin.","forgot-password":"Passwort vergessen?","forgot-password-title":"Passwort vergessen","forgot-password-email":"E-Mail","forgot-password-submit":"Absenden","forgot-password-text":"Gib deine E-Mailadresse in das Feld ein. Ist die Adresse registriert, werden wir eine E-Mail mit einem Passwort-Resetcode senden.","no-user-found":"Es gibt keinen Benutzer mit dieser E-Mailadresse","new-password-code-send":"Es wurde ein Reset-Code an deine E-Mailadresse gesendet.","new-password":"Neues Passwort","new-password-password1":"Passwort","new-password-password2":"Passwort wiederholen","new-password-submit":"Passwort setzten","password-updated":"Das Passwort ist geupdated!","user-settings":"E-Mail & Username","user-settings-title":"E-Mail & Username","user-settings-form-username":"Username","user-settings-form-old-email":"Aktuelle E-Mail","user-settings-form-new-email":"Neue E-Mail","user-settings-form-submit":"Speichern","user-data-is-changed":"Die Daten wurden gespeichert.","email-code-send":"Ein Änderungscode wurde an die neue E-Mailadresse gesendet. Sobald der Code aktiviert wurde, werden Ihnen E-Mails an die neue Adresse gesendet.","change-email-new-automated-login":"Wenn die E-Mailadresse geändert wird, muss der automatische Login erneut aktiviert werden!","password-settings":"Passwort","change-password-title":"Passwort","change-password-new-automated-login":"Wenn das Passwort geändert wird, muss der automatische Login erneut aktiviert werden!","change-password-old-password":"Altes Passwort","change-password-new-password1":"Neues Passwort","change-password-new-password2":"Neues Passwort wiederholen","change-password-submit":"Speichern","password-changed":"Das Passwort wurde erfolgreich geändert!","registration-username-empty":"Der Username darf nicht leer sein.","registration-username-wrong-char":"Der Username darf nur aus Buchstaben, Zahlen oder den folgenden Zeichen bestehen: -_.&;()#!?$+\",","registration-username-already-taken":"Der Username ist schon vergeben. Bitte wähle einen anderen.","registration-password-empty":"Das Passwort darf nicht leer sein.","registration-password-short":"Das Passwort muss mindestens 8 Zeichen lang sein.","registration-password-not-identical":"Die Passwörter sind nicht identlisch.","registration-email-empty":"Die Email darf nicht leer sein.","registration-email-not-valid":"Die Emailadresse ist keine gültige Emailadresse.","registration-email-already-taken":"Es gibt bereits einen Account mit der Emailadresse.","change-password-old-password-wrong":"Das Passwort stimmt nicht!","user-roles-heading":"Benutzerrollen","user-roles-list":"Aktuelle Rollen:","available-roles-list":"Verfügbare Rollen:","name":"Name","description":"Beschreibung"} \ No newline at end of file +{"won":"Gewonnen!","continue":"Weiter","help":"?","not-enough-coins":"Du hast zu wenig Münzen!","sync-error":"Es gab einen Fehler beim Aktualisieren der Level. Bitte stelle sicher, dass du eine aktive Internetverbindung hast und versuche es später erneut.","game-ended":"Oh nein!
Es sieht so aus, als ob du schon alle Level gespielt hast...
Schau später noch einmal rein, evtl gibt es dann neue Level.","play":"Spielen!","tutorial-step-1":"Klicke auf ein Feld, um dieses rotieren zu lassen!","tutorial-step-2":"Um zu gewinnen, drehe die Segmente so, dass du zwei Wörter lesen kannst.","tutorial-step-3":"Die Hilfe löst ein Segment, kostet aber 25 Münzen. Probiere jetzt die Hilfe aus.","tutorial-step-4":"Große Segmente drehst du, indem du diese ziehst.","extra-coins-after-first-level":"Für das erste Level gibt es 50 extra Münzen!","dark":"Dunkel","theme":"Theme:","sound":"Sound:","music":"Musik:","credits":"Credits","privacy-policy":"Datenschutzbestimmungen","impressum":"Impressum","track":"Anonymisierte Nutzungsdaten senden:",">":">","choose-theme-dialog-title":"Theme auswählen:","install":"Installieren","share-dialog":"Teilen:","Sunday":"Sonntag","Monday":"Montag","Tuesday":"Dienstag","Wednesday":"Mittwoch","Thursday":"Donnerstag","Friday":"Freitag","Saturday":"Samstag","January":"Januar","February":"Februar","March":"März","April":"April","May":"Mai","June":"Juni","July":"Juli","August":"August","September":"September","October":"Oktober","November":"November","December":"Dezember","Sun":"So","Mon":"Mo","Tue":"Di","Wed":"Mi","Thu":"Do","Fri":"Fr","Sat":"Sa","Jan":"Jan","Feb":"Feb","Mar":"Mär","Apr":"Apr","Jun":"Jun","Jul":"Jul","Aug":"Aug","Sep":"Sep","Oct":"Okt","Nov":"Nov","Dec":"Dez","code-not-valid":"Der angegebebe Code ist nicht gültig!","code-activated":"Der Code wurde erfolgreich aktiviert!","current-lang":"DE","en":"Englisch","de":"Deutsch","black":"Schwarz","red":"Rot","blue":"Blau","green":"Grün","pink":"Rosa","cancel-button":"ABBRECHEN","confirm-button":"OK","we-use-cookie-hint":"Diese Seite nutzt Cookies. Durch das weitere Benutzen dieser Seite geben Sie uns das Recht Cookies so zu benutzen, wie es in unserer Datenschutzerklärung steht.","policy-heading":"Datenschutzerklärung","area-of-validity-heading":"Geltungsbereich","area-of-validity":"Diese Datenschutzerklärung klärt Nutzer über die Art, den Umfang und Zwecke der Erhebung und Verwendung personenbezogener Daten durch den verantwortlichen Anbieter Silas Günther, Langenbusch 263b - 42897 Remscheid, matrix[at]silas.link auf dieser Website (im folgenden \"Angebot\") auf.

Die rechtlichen Grundlagen des Datenschutzes finden sich im Bundesdatenschutzgesetz (BDSG) und dem Telemediengesetz (TMG).","logfiles-heading":"Zugriffsdaten / Server-Logfiles","logfiles":"Der Anbieter (beziehungsweise sein Webspace-Provider) erhebt Daten über jeden Zugriff auf das Angebot (so genannte Serverlogfiles). Zu den Zugriffsdaten gehören:

Name der abgerufenen Webseite, Datei, Datum und Uhrzeit des Abrufs, übertragene Datenmenge, Meldung über erfolgreichen Abruf, Browsertyp nebst Version, das Betriebssystem des Nutzers, Referrer URL (die zuvor besuchte Seite), IP-Adresse und der anfragende Provider.

Der Anbieter verwendet die Protokolldaten nur für statistische Auswertungen zum Zweck des Betriebs, der Sicherheit und der Optimierung des Angebotes. Der Anbieter behält sich jedoch vor, die Protokolldaten nachträglich zu überprüfen, wenn aufgrund konkreter Anhaltspunkte der berechtigte Verdacht einer rechtswidrigen Nutzung besteht.","contact-support-heading":"Kontaktaufnahme","contact-support":"Bei der Kontaktaufnahme mit dem Anbieter (zum Beispiel per Post oder E-Mail) werden die Angaben des Nutzers zwecks Bearbeitung der Anfrage sowie für den Fall, dass Anschlussfragen entstehen, gespeichert.","cookies-heading":"Cookies","cookies":"Cookies sind kleine Dateien, die es ermöglichen, auf dem Zugriffsgerät der Nutzer (PC, Smartphone o.ä.) spezifische, auf das Gerät bezogene Informationen zu speichern. Sie dienen zum einem der Benutzerfreundlichkeit von Webseiten und damit den Nutzern (z.B. Speicherung von Logindaten). Zum anderen dienen sie, um die statistische Daten der Webseitennutzung zu erfassen und sie zwecks Verbesserung des Angebotes analysieren zu können. Die Nutzer können auf den Einsatz der Cookies Einfluss nehmen. Die meisten Browser verfügen eine Option mit der das Speichern von Cookies eingeschränkt oder komplett verhindert wird. Allerdings wird darauf hingewiesen, dass die Nutzung und insbesondere der Nutzungskomfort ohne Cookies eingeschränkt werden.

Sie können viele Online-Anzeigen-Cookies von Unternehmen über die US-amerikanische Seite http://www.aboutads.info/choices/ oder die EU-Seite http://www.youronlinechoices.com/uk/your-ad-choices/ verwalten.","google-analytics-heading":"Google Analytics","google-analytics":"Dieses Angebot benutzt Google Analytics, einen Webanalysedienst der Google Inc. („Google“). Google Analytics verwendet sog. „Cookies“, Textdateien, die auf Computer der Nutzer gespeichert werden und die eine Analyse der Benutzung der Website durch sie ermöglichen. Die durch den Cookie erzeugten Informationen über Benutzung dieser Website durch die Nutzer werden in der Regel an einen Server von Google in den USA übertragen und dort gespeichert.

Im Falle der Aktivierung der IP-Anonymisierung auf dieser Webseite, wird die IP-Adresse der Nutzer von Google jedoch innerhalb von Mitgliedstaaten der Europäischen Union oder in anderen Vertragsstaaten des Abkommens über den Europäischen Wirtschaftsraum zuvor gekürzt. Nur in Ausnahmefällen wird die volle IP-Adresse an einen Server von Google in den USA übertragen und dort gekürzt. Die IP-Anonymisierung ist auf dieser Website aktiv. Im Auftrag des Betreibers dieser Website wird Google diese Informationen benutzen, um die Nutzung der Website durch die Nutzer auszuwerten, um Reports über die Websiteaktivitäten zusammenzustellen und um weitere mit der Websitenutzung und der Internetnutzung verbundene Dienstleistungen gegenüber dem Websitebetreiber zu erbringen.

Die im Rahmen von Google Analytics von Ihrem Browser übermittelte IP-Adresse wird nicht mit anderen Daten von Google zusammengeführt. Die Nutzer können die Speicherung der Cookies durch eine entsprechende Einstellung Ihrer Browser-Software verhindern; Dieses Angebot weist die Nutzer jedoch darauf hin, dass Sie in diesem Fall gegebenenfalls nicht sämtliche Funktionen dieser Website vollumfänglich werden nutzen können. Die Nutzer können darüber hinaus die Erfassung der durch das Cookie erzeugten und auf ihre Nutzung der Website bezogenen Daten (inkl. Ihrer IP-Adresse) an Google sowie die Verarbeitung dieser Daten durch Google verhindern, indem sie das unter dem folgenden Link verfügbare Browser-Plugin herunterladen und installieren: http://tools.google.com/dlpage/gaoptout?hl=de.

Weitere Informationen zur Datennutzung zu Werbezwecken durch Google, Einstellungs- und Widerspruchsmöglichkeiten erfahren Sie auf den Webseiten von Google:
https://www.google.com/intl/de/policies/privacy/partners/ („Datennutzung durch Google bei Ihrer Nutzung von Websites oder Apps unserer Partner“),
http://www.google.com/policies/technologies/ads („Datennutzung zu Werbezwecken“),
http://www.google.de/settings/ads („Informationen verwalten, die Google verwendet, um Ihnen Werbung einzublenden“) und
http://www.google.com/ads/preferences/ („Bestimmen Sie, welche Werbung Google Ihnen zeigt“).","edited-hint":"Der generierte Text wurde vom Webseiteninhaber angepasst.","generated-hint":"Erstellt mit Datenschutz-Generator.de von RA Dr. Thomas Schwenke","google-play-services-heading":"Google Play Dienste","google-play-services":"Features wie die Bestenliste und Erfolge benötigen einen Login bei Google Play. Hierfür wird die Identität benötigt, um die entsprechenden Punktzahlen und Erfolge an das jeweilige Google Play-Konto zu knüpfen. Alle anderen Features sind weiterhin auch ohne Login bei Google Play nutzbar. Außerdem kann sich jederzeit in den Einstellungen von Google Play abgemeldet werden.","settings":"Einstellungen","close":"Schließen","other-apps":"Andere Apps","optimistic-locking-dialog":"Deine Änderungen können nicht gespeichert werden! Ein anderer Benutzer hat die Daten bereits verändert. Bitte lade die Daten neu und speichere danach.","optimistic-locking-dialog-title":"Nicht gespeichert!","not-online":"Du bist nicht mit dem Internet verbunden. Bitte überprüfe deine Verbindung.","search":"Suchen...","site":"Seite","HTTP-Exception (403) Forbidden":"Nicht erlaubt!","login":"Login","login-email":"E-Mail","login-password":"Passwort","login-automated-login":"Automatischer Login","login-submit":"Login","logout":"Ausloggen","username-or-password-wrong":"Entweder der Username oder das Passwort stimmt nicht!","login-success":"Willkommen zurück!","logged-out-successfully":"Tschüss!","registration":"Registrieren","registration-username":"Username","registration-email":"E-Mail","registration-password1":"Passwort","registration-password2":"Passwort wiederholen","registration-submit":"Registrieren","registration-success":"Ein Registrierungscode wurde an Ihre E-Mailadresse gesendet.","not-allowed-title":"Nicht erlaubt!","not-allowed":"Du hast keine Berechtigung für diese Seite. Wenn das ein Fehler ist, wende dich bitte an einen Admin.","forgot-password":"Passwort vergessen?","forgot-password-title":"Passwort vergessen","forgot-password-email":"E-Mail","forgot-password-submit":"Absenden","forgot-password-text":"Gib deine E-Mailadresse in das Feld ein. Ist die Adresse registriert, werden wir eine E-Mail mit einem Passwort-Resetcode senden.","no-user-found":"Es gibt keinen Benutzer mit dieser E-Mailadresse","new-password-code-send":"Es wurde ein Reset-Code an deine E-Mailadresse gesendet.","new-password":"Neues Passwort","new-password-password1":"Passwort","new-password-password2":"Passwort wiederholen","new-password-submit":"Passwort setzten","password-updated":"Das Passwort ist geupdated!","user-settings":"E-Mail & Username","user-settings-title":"E-Mail & Username","user-settings-form-username":"Username","user-settings-form-old-email":"Aktuelle E-Mail","user-settings-form-new-email":"Neue E-Mail","user-settings-form-submit":"Speichern","user-data-is-changed":"Die Daten wurden gespeichert.","email-code-send":"Ein Änderungscode wurde an die neue E-Mailadresse gesendet. Sobald der Code aktiviert wurde, werden Ihnen E-Mails an die neue Adresse gesendet.","change-email-new-automated-login":"Wenn die E-Mailadresse geändert wird, muss der automatische Login erneut aktiviert werden!","password-settings":"Passwort","change-password-title":"Passwort","change-password-new-automated-login":"Wenn das Passwort geändert wird, muss der automatische Login erneut aktiviert werden!","change-password-old-password":"Altes Passwort","change-password-new-password1":"Neues Passwort","change-password-new-password2":"Neues Passwort wiederholen","change-password-submit":"Speichern","password-changed":"Das Passwort wurde erfolgreich geändert!","registration-username-empty":"Der Username darf nicht leer sein.","registration-username-wrong-char":"Der Username darf nur aus Buchstaben, Zahlen oder den folgenden Zeichen bestehen: -_.&;()#!?$+\",","registration-username-already-taken":"Der Username ist schon vergeben. Bitte wähle einen anderen.","registration-password-empty":"Das Passwort darf nicht leer sein.","registration-password-short":"Das Passwort muss mindestens 8 Zeichen lang sein.","registration-password-not-identical":"Die Passwörter sind nicht identlisch.","registration-email-empty":"Die Email darf nicht leer sein.","registration-email-not-valid":"Die Emailadresse ist keine gültige Emailadresse.","registration-email-already-taken":"Es gibt bereits einen Account mit der Emailadresse.","change-password-old-password-wrong":"Das Passwort stimmt nicht!","user-roles-heading":"Benutzerrollen","user-roles-list":"Aktuelle Rollen:","available-roles-list":"Verfügbare Rollen:","name":"Name","description":"Beschreibung"} \ No newline at end of file diff --git a/src/js/init.js b/src/js/init.js index 8e2f0e6..2170936 100755 --- a/src/js/init.js +++ b/src/js/init.js @@ -18,7 +18,7 @@ import "./lib/pwa-user-management" import {SettingsManager, SettingsSite} from "./lib/pwa-core"; -import {InstallManager, Matomo, SoundManager} from "./lib/pwa-assets"; +import {InstallManager, Matomo, MatomoShareButton, SoundManager} from "./lib/pwa-assets"; import {MenuSite} from "../module/Application/pwa/js/site/MenuSite"; import {WordRotatorSettingFragment} from "../module/Application/pwa/js/Fragment/WordRotatorSettingFragment"; @@ -37,9 +37,9 @@ ThemeManager.addTheme(new Theme("green", "green")); ThemeManager.addTheme(new Theme("pink", "pink")); ThemeManager.addTheme(new Theme("dark", "dark")); -ShareManager.addShareButton(new WhatsappShareButton('img/whatsapp.svg', true)); -ShareManager.addShareButton(new SmsShareButton('img/sms.svg', true)); -ShareManager.addShareButton(new TelegramShareButton('img/telegram.svg', true)); +ShareManager.addShareButton(new MatomoShareButton(new WhatsappShareButton('img/whatsapp.svg'), "whatsapp", true)); +ShareManager.addShareButton(new MatomoShareButton(new SmsShareButton('img/sms.svg'), "sms", true)); +ShareManager.addShareButton(new MatomoShareButton(new TelegramShareButton('img/telegram.svg'), "telegram", true)); // ShareManager.addShareButton(new CopyShareButton('img/copy.svg')); let app = new App(); diff --git a/src/js/lib/pwa-assets.js b/src/js/lib/pwa-assets.js index 5aebfdf..88a5b02 100755 --- a/src/js/lib/pwa-assets.js +++ b/src/js/lib/pwa-assets.js @@ -1,4 +1,4 @@ -import { Helper, InitPromise, Fragment, Translator } from './pwa-lib.js'; +import { Helper, InitPromise, MultipleShareButton, Fragment, Translator } from './pwa-lib.js'; class DelayPromise extends Promise { static async delay(delay) { @@ -74,16 +74,13 @@ class Matomo { g.src = Matomo.TRACK_SITE + '/piwik.js'; s.appendChild(g); }); - // window.addEventListener('hashchange', () => { - // Matomo.update() - // }); } static update(title) { - if (Helper.nonNull(Matomo.currentUrl)){ + if (Helper.nonNull(Matomo.currentUrl)) { Matomo.push(['setReferrerUrl', Matomo.currentUrl]); } - Matomo.currentUrl = window.location.pathname+window.location.search; + Matomo.currentUrl = window.location.pathname + window.location.search; Matomo.push(['setCustomUrl', Matomo.currentUrl]); Matomo.push(['setDocumentTitle', title]); @@ -109,17 +106,10 @@ class Matomo { resolve(!this["isUserOptedOut"]()); }]); }); - // Matomo.isTrackingPromise = Matomo.query("isTracked") - // .then(xml => { - // let textContent = xml.firstChild.textContent; - // // localStorage.setItem(Matomo.LOCAL_STORAGE_KEY, textContent); - // return (textContent === "1") - // }); return Matomo.isTrackingPromise; } - static - async query(method) { + static async query(method) { return fetch(Matomo.TRACK_SITE + Matomo.BASE_PATH + method, { "mode": "cors", "credentials": "include", @@ -130,11 +120,10 @@ class Matomo { return Matomo.isTrackingPromise; } - static - async setTrack(shouldTrack) { + static async setTrack(shouldTrack) { Matomo.isTrackingPromise = Promise.resolve(shouldTrack); localStorage.setItem(Matomo.LOCAL_STORAGE_KEY, (shouldTrack === true) ? "1" : "0"); - // return await Matomo.query((shouldTrack) ? "doTrack" : "doIgnore"); + if (shouldTrack) { Matomo.push(["forgetUserOptOut"], true); } @@ -143,16 +132,24 @@ class Matomo { } } - static - async push(arr, force) { - // force = Helper.nonNull(force, false); + static async trackEvent(event, name, label, value){ + let ev = ["trackEvent", event, name]; + if (Helper.isNotNull(label)){ + ev.push(label); + } + if (Helper.isNotNull(value) && !isNaN(parseFloat(value)) && isFinite(value)){ + ev.push(value); + } + + return this.push(ev); + } + + static async push(arr, force) { if (!Array.isArray(arr)) { arr = [arr]; } - // if (force || await Matomo.getTrackingPromise()) { window["_paq"].push(arr); - // } } } @@ -168,6 +165,15 @@ InitPromise.addPromise(() => { Matomo.init(); }); +class MatomoShareButton extends MultipleShareButton{ + + constructor(baseButton, platform, shouldLoadImg) { + super([baseButton, (url) => { + Matomo.trackEvent("shared", url, platform); + }], shouldLoadImg); + } +} + class RotateHelper { rotate(element, degrees){ let rotateText = element.innerText; @@ -527,4 +533,4 @@ class TabbedFragment extends Fragment { } } -export { DelayPromise, InstallManager, Matomo, RotateHelper, ScaleHelper, AudioChain, SoundManager, TabbedFragment }; +export { DelayPromise, InstallManager, Matomo, MatomoShareButton, RotateHelper, ScaleHelper, AudioChain, SoundManager, TabbedFragment }; diff --git a/src/js/lib/pwa-lib.js b/src/js/lib/pwa-lib.js index 004dc5d..8d99d5f 100755 --- a/src/js/lib/pwa-lib.js +++ b/src/js/lib/pwa-lib.js @@ -3665,7 +3665,7 @@ class ShareButton { this._deviceType = deviceType; this._icon = icon; this._callback = callback; - console.log("shouldLoad", Helper.nonNull(shouldLoadImg, false), shouldLoadImg); + if (Helper.nonNull(shouldLoadImg, false)){ this._icon = ViewInflater.inflate(this._icon); } @@ -3723,6 +3723,34 @@ class CopyShareButton extends ShareButton } } +class MultipleShareButton extends ShareButton{ + constructor(deviceType, icon, callbacks, shouldLoadImg) + { + console.log(Array.isArray(deviceType), deviceType[0] instanceof ShareButton); + if (Array.isArray(deviceType) && deviceType[0] instanceof ShareButton){ + let btn = deviceType[0]; + deviceType = btn._deviceType; + icon = btn._icon; + callbacks = deviceType; + shouldLoadImg = Helper.nonNull(shouldLoadImg, icon); + } + + super(deviceType, icon, function (link, element, event) { + if (!Array.isArray(callbacks)){ + callbacks = [callbacks]; + } + for (let i = 0; i < callbacks.length; i++) { + if (callbacks[i] instanceof ShareButton){ + callbacks[i].getCallback()(link, element, event); + } + else { + callbacks[i](link, element, event); + } + } + }, shouldLoadImg); + } +} + class ShareManager { static init() { ShareManager.shareButtons = []; @@ -4327,4 +4355,4 @@ function applyPolyfills() { }); } -export { App, ChainAble, CookieCompliance, ConfirmDialog, Dialog, FlashMessenger, AbstractService, AbstractGapiResponse, Achievement, AchievementList, GameService, GapiPlayer, Leaderboard, Score, GapiHandler, Helper, InitPromise, ActionBarMenu, Menu, MenuAction, OpenSubmenuAction, Submenu, MyDb, Prioritised, ScriptLoader, CopyShareButton, ShareButton, ShareManager, SmsShareButton, TelegramShareButton, WhatsappShareButton, SimpleWS, AbstractSite, Context, Fragment, PauseSite, SiteContainer, SiteManager, SystemSettings, Theme, ThemeManager, DBTranslator, Translator, TranslatorDB, ViewInflater, applyPolyfills }; +export { App, ChainAble, CookieCompliance, ConfirmDialog, Dialog, FlashMessenger, AbstractService, AbstractGapiResponse, Achievement, AchievementList, GameService, GapiPlayer, Leaderboard, Score, GapiHandler, Helper, InitPromise, ActionBarMenu, Menu, MenuAction, OpenSubmenuAction, Submenu, MyDb, Prioritised, ScriptLoader, CopyShareButton, MultipleShareButton, ShareButton, ShareManager, SmsShareButton, TelegramShareButton, WhatsappShareButton, SimpleWS, AbstractSite, Context, Fragment, PauseSite, SiteContainer, SiteManager, SystemSettings, Theme, ThemeManager, DBTranslator, Translator, TranslatorDB, ViewInflater, applyPolyfills }; diff --git a/src/module/Application/pwa/js/Fragment/WordRotatorSettingFragment.js b/src/module/Application/pwa/js/Fragment/WordRotatorSettingFragment.js index 5147d9b..92621a6 100644 --- a/src/module/Application/pwa/js/Fragment/WordRotatorSettingFragment.js +++ b/src/module/Application/pwa/js/Fragment/WordRotatorSettingFragment.js @@ -67,6 +67,9 @@ export class WordRotatorSettingFragment extends LocalStorageSettingsFragment { installButton.classList.add("hidden"); InstallManager.prompt().then((e) => { console.log("clicked", e); + if (e["outcome"] === "accepted"){ + Matomo.trackEvent("installed", "installed") + } }); }); installButton.classList.remove("hidden"); diff --git a/src/module/Application/pwa/translations/de.json b/src/module/Application/pwa/translations/de.json index d0aba7a..f319499 100755 --- a/src/module/Application/pwa/translations/de.json +++ b/src/module/Application/pwa/translations/de.json @@ -12,7 +12,7 @@ "tutorial-step-1": "Klicke auf ein Feld, um dieses rotieren zu lassen!", "tutorial-step-2": "Um zu gewinnen, drehe die Segmente so, dass du zwei Wörter lesen kannst.", - "tutorial-step-3": "Durch die Hilfe kannst du ein Segment lösen lassen. Die Hilfe kostet aber 25 Münzen. Probiere jetzt die Hilfe aus.", + "tutorial-step-3": "Die Hilfe löst ein Segment, kostet aber 25 Münzen. Probiere jetzt die Hilfe aus.", "tutorial-step-4": "Große Segmente drehst du, indem du diese ziehst.", "extra-coins-after-first-level":"Für das erste Level gibt es 50 extra Münzen!",