From fed138abc2ed895ae0656705a193a7a34685e402 Mon Sep 17 00:00:00 2001
From: les
Date: Sun, 21 Mar 2021 22:44:54 +0100
Subject: [PATCH 001/113] fix digest httpsignature header
---
server/federation/follows.js | 2 +-
server/federation/helpers.js | 17 ++++++++++++-----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/server/federation/follows.js b/server/federation/follows.js
index deba6365..6d0d1274 100644
--- a/server/federation/follows.js
+++ b/server/federation/follows.js
@@ -25,7 +25,7 @@ module.exports = {
'actor': `${config.baseurl}/federation/u/${username}`,
'object': body
}
- Helpers.signAndSend(message, req.fedi_user.object.inbox)
+ Helpers.signAndSend(JSON.stringify(message), req.fedi_user.object.inbox)
res.sendStatus(200)
},
diff --git a/server/federation/helpers.js b/server/federation/helpers.js
index 2765732a..7aa5f866 100644
--- a/server/federation/helpers.js
+++ b/server/federation/helpers.js
@@ -35,23 +35,28 @@ const Helpers = {
const privkey = settingsController.secretSettings.privateKey
const signer = crypto.createSign('sha256')
const d = new Date()
- const stringToSign = `(request-target): post ${inboxUrl.pathname}\nhost: ${inboxUrl.hostname}\ndate: ${d.toUTCString()}`
+ // digest header added for Mastodon 3.2.1 compatibility
+ const digest = crypto.createHash('sha256')
+ .update(message)
+ .digest('base64')
+ const stringToSign = `(request-target): post ${inboxUrl.pathname}\nhost: ${inboxUrl.hostname}\ndate: ${d.toUTCString()}\ndigest: SHA-256=${digest}`
signer.update(stringToSign)
signer.end()
const signature = signer.sign(privkey)
const signature_b64 = signature.toString('base64')
- const header = `keyId="${config.baseurl}/federation/u/${settingsController.settings.instance_name}",headers="(request-target) host date",signature="${signature_b64}"`
+ const header = `keyId="${config.baseurl}/federation/u/${settingsController.settings.instance_name}",algorithm="rsa-sha256",headers="(request-target) host date digest",signature="${signature_b64}"`
try {
const ret = await axios(inbox, {
headers: {
Host: inboxUrl.hostname,
Date: d.toUTCString(),
Signature: header,
+ Digest: `SHA-256=${digest}`,
'Content-Type': 'application/activity+json; charset=utf-8',
Accept: 'application/activity+json, application/json; chartset=utf-8'
},
method: 'post',
- data: JSON.stringify(message)
+ data: message
})
debug('sign %s => %s', ret.status, ret.data)
} catch (e) {
@@ -88,8 +93,10 @@ const Helpers = {
body['@context'] = [
'https://www.w3.org/ns/activitystreams',
'https://w3id.org/security/v1',
- { Hashtag: 'as:Hashtag' }]
- Helpers.signAndSend(body, sharedInbox)
+ {
+ Hashtag: 'as:Hashtag'
+ }]
+ await Helpers.signAndSend(JSON.stringify(body), sharedInbox)
}
},
From 6f838d120dc05c43e4dd4e3404eff4bbcd533c85 Mon Sep 17 00:00:00 2001
From: les
Date: Sun, 21 Mar 2021 22:46:35 +0100
Subject: [PATCH 002/113] v0.24.4
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 213e8819..390b9851 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "gancio",
- "version": "0.24.3",
+ "version": "0.24.4",
"description": "A shared agenda for local communities",
"author": "lesion",
"scripts": {
From e67aa016493af969092754fa11a2f3b05f25ac1a Mon Sep 17 00:00:00 2001
From: "J. Lavoie"
Date: Sun, 28 Mar 2021 12:37:56 +0000
Subject: [PATCH 003/113] Translated using Weblate (Italian)
Currently translated at 100.0% (226 of 226 strings)
Translation: Gancio/Web
Translate-URL: https://hosted.weblate.org/projects/gancio/web/it/
---
locales/it.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/locales/it.json b/locales/it.json
index 403932a4..6ace3293 100644
--- a/locales/it.json
+++ b/locales/it.json
@@ -102,7 +102,7 @@
"export": {
"intro": "Contrariamente alle piattaforme del capitalismo, che fanno di tutto per tenere i dati e gli utenti al loro interno, crediamo che le informazioni, come le persone, debbano essere libere. Per questo puoi rimanere aggiornata sugli eventi che vuoi, come meglio credi, senza necessariamente passare da questo sito.",
"email_description": "Puoi ricevere via posta elettronica gli eventi che ti interessano.",
- "insert_your_address": "Indirizzo e-mail",
+ "insert_your_address": "Inserisci il tuo indirizzo e-mail",
"feed_description": "Per seguire gli aggiornamenti da computer o smartphone senza la necessità di aprire periodicamente il sito, il metodo consigliato è quello dei Feed RSS.
\n\n Con i feed rss utilizzi un'apposita applicazione per ricevere aggiornamenti dai siti che più ti interessano. È un buon metodo per seguire anche molti siti in modo molto rapido, senza necessità di creare un account o altre complicazioni.
\n\nSe hai Android, ti consigliamo Flym o Feeder\nPer iPhone/iPad puoi usare Feed4U\nPer il computer fisso/portatile consigliamo Brief, da installare all'interno di Firefox e compatibile con tutti i principali sistemi operativi.\n
\nAggiungendo questo link al tuo lettore di feed, rimarrai aggiornata.",
"ical_description": "I computer e gli smartphone sono comunemente attrezzati con un'applicazione per gestire un calendario. A questi programmi solitamente è possibile far importare un calendario remoto.",
"list_description": "Se hai un sito web e vuoi mostrare una lista di eventi, puoi usare il seguente codice"
From 745dd7858db1b6791e8e265874971abb63dc8c6e Mon Sep 17 00:00:00 2001
From: les
Date: Tue, 30 Mar 2021 09:35:26 +0200
Subject: [PATCH 004/113] remove duplicated nb locale
---
locales/nb_NO.json | 258 ---------------------------------------------
1 file changed, 258 deletions(-)
delete mode 100644 locales/nb_NO.json
diff --git a/locales/nb_NO.json b/locales/nb_NO.json
deleted file mode 100644
index 19c9be38..00000000
--- a/locales/nb_NO.json
+++ /dev/null
@@ -1,258 +0,0 @@
-{
- "oauth": {
- "scopes": {
- "event:write": "Legg til og rediger dine hendelser"
- },
- "redirected_to": "Etter bekreftelse vil du bli videresendt til {url}
",
- "authorization_request": "Programmet {app}
ber om følgende autorisering på {instance_name}
:"
- },
- "confirm": {
- "title": "Brukerbekreftelse",
- "valid": "Kontoen din er bekreftet, du kan nå logge inn",
- "not_valid": "Noe gikk galt."
- },
- "error": {
- "email_taken": "Denne e-postadressen er allerede i bruk",
- "nick_taken": "Dette kallenavnet er allerede i bruk."
- },
- "settings": {
- "password_updated": "Passord endret",
- "change_password": "Endre passord",
- "remove_account_confirm": "Du er i ferd med å slette kontoen din for godt",
- "remove_account": "Ved å trykke på følgende knapp vil din brukerkonto slettes. Hendelser du har offentliggjort vil ikke bli det.",
- "danger_section": "Farlig del",
- "update_confirm": "Ønsker du å lagre endringen?"
- },
- "auth": {
- "not_confirmed": "Ikke bekreftet enda…",
- "fail": "Kunne ikke logge inn. Er du sikker på at passordet stemmer?"
- },
- "admin": {
- "new_announcement": "Ny kunngjøring",
- "edit_place": "Rediger sted",
- "delete_footer_link_confirm": "Er du sikker på at du vil fjerne denne lenken?",
- "add_link": "Legg til lenke",
- "is_dark": "Mørk drakt",
- "instance_locale": "Forvalgt språk",
- "announcement_remove_ok": "Kunngjøring fjernet",
- "delete_announcement_confirm": "Er du sikker på at du vil fjerne denne kunngjøringen?",
- "user_block_confirm": "Er du sikker på at du vil blokkere denne brukeren?",
- "favicon": "Logo",
- "resources": "Ressurser",
- "filter_users": "Filtrer brukere",
- "filter_instances": "Filtrer instanser",
- "block_user": "Blokker bruker",
- "delete_resource_confirm": "Er du sikker på at du vil slette denne ressursen?",
- "delete_resource": "Slett ressurs",
- "hide_resource": "Skjul ressurs",
- "show_resource": "Vis ressurs",
- "instance_name": "Instansens navn",
- "unblock": "Opphev blokkering",
- "block": "Blokker",
- "enable_resources": "Skru på ressurser",
- "select_instance_timezone": "Tidssone",
- "user_create_ok": "Bruker opprettet",
- "user_remove_ok": "Bruker fjernet",
- "delete_user_confirm": "Er du sikker på at du vil fjerne denne brukeren?",
- "remove_admin": "Fjern administrator",
- "delete_user": "Fjern",
- "footer_links": "Bunntekst-lenker",
- "delete_trusted_instance_confirm": "Ønsker du virkelig å slette dette elementet fra venneinstansmenyen?",
- "instance_place_help": "Etikett å vise i andres instanser",
- "add_trusted_instance": "Legg til en vennlig instans",
- "trusted_instances_help": "Liste over vennlige instanser vises i toppteksten",
- "enable_trusted_instances": "Skru på vennlige instanser",
- "instance_name_help": "ActivityPub-konto å følge",
- "instance_place": "Indiker sted for denne instansen",
- "description_description": "Vises i toppteksten ved siden av tittelen",
- "title_description": "Det brukes som overskrift på siden, i emnet av e-posten for eksportering til RSS- og ICS-informasjonsstrømmer.",
- "instance_locale_description": "Foretrukket brukerspråk for sider. Noen meldinger vises påsamme bruk for alle (for eksempel ved publisering via ActivityPub, eller ved forsendelse av noen e-poster). I sådant fall vil språket ovenfor bli brukt.",
- "instance_timezone_description": "Gancio er designet for å samle hendelser fra et gitt sted, som en by. Alle hendelser på dette stedet vil bli vist i tidssonen valgt for det.",
- "announcement_description": "I denne delen kan du smette inn kunngjøringer som forblir på hjemmesiden",
- "user_blocked": "Brukeren {user} blokkert",
- "user_add_help": "En e-post med instruks om bekreftelse av abonnementet og valg av passord vil bli sendt til den nye brukeren",
- "hide_boost_bookmark_help": "Skjuler de små ikonene som viser antall framhevelser og bokmerker som kommer fra fediverset",
- "hide_boost_bookmark": "Skjuler framhevelser/bokmerker",
- "enable_resources_help": "Tillat tillegg av ressurser til hendelsen fra fediverset",
- "enable_federation_help": "Det vil bli mulig å følge denne instansen fra fediverset",
- "enable_federation": "Skru på føderasjon",
- "federation": "Føderasjon/ActivityPub",
- "recurrent_event_visible": "Vis gjentagende hendelser som forvalg",
- "allow_recurrent_event": "Tillat gjentagende hendelser",
- "allow_anon_event": "Tillat anonyme hendelser (må bekreftes)?",
- "allow_registration_description": "Tillat selv-registrering?",
- "event_confirm_description": "Du kan bekrefte hendelser som oppføres av anonyme brukere her",
- "place_description": "Hvis du har valgt feil sted eller adresse, kan du endre det.
Alle nåværende og foregående hendelser tilknyttet dette stedet vil endre adresse."
- },
- "event": {
- "interact_with_me": "Følg meg",
- "from": "Fra",
- "due": "til",
- "each_month": "Hver måed",
- "each_2w": "Annenhver uke",
- "each_week": "Hver uke",
- "recurrent_1w_days": "Hver {days}",
- "normal_description": "Velg dagen.",
- "normal": "Normal",
- "multidate": "Flere dager",
- "recurrent_description": "Velg hyppighet og velg dagene",
- "only_future": "kun kommende hendelser",
- "show_past": "også i fortid",
- "show_recurrent": "gjentagende hendelser",
- "recurrent": "Gjentagende",
- "remove_confirmation": "Er du sikker på at du vil fjerne denne hendelsen?",
- "not_found": "Fant ikke hendelse",
- "confirmed": "Hendelse bekreftet",
- "tag_description": "Etikett",
- "description_description": "Beskrivelse",
- "what_description": "Tittel",
- "same_day": "på samme dag",
- "anon": "Anon",
- "follow_me_description": "Én av måtene å holde deg oppdatert på hendelser som publiseres her på {title}\ner å følge kontoen {account} fra fediverset, for eksempel via Gab, og også legge til ressurser til en hendelser derfra.
\nHvis du aldri har hørt om Gab eller fediverset anbefales denne artikkelen.
Skriv inn din instans nedenfor (f.eks. social.librem.one)",
- "remove_recurrent_confirmation": "Er du sikker på at du ønsker å fjerne denne gjentagende hendelsen?\nHendelser i fortiden vil forbli, men ingen videre hendelser vil bli opprettet.",
- "interact_with_me_at": "Snakk til meg i fediverset på",
- "image_too_big": "Bildet kan ikke være større enn 4 MB",
- "recurrent_2m_ordinal": "|Den {n} {days} i måneden annenhver|Den {n} {days} i måneden annenhver",
- "recurrent_1m_ordinal": "På {n} {days} i hver måned",
- "recurrent_2m_days": "|På {days} i hver måned annenhver|{days} i hver måned annenhver",
- "recurrent_1m_days": "|På {days} i hver måned|{days} i hver måned",
- "recurrent_2w_days": "En {days} annenhver",
- "multidate_description": "Er det en festival? Velg når den starter og slutter",
- "where_description": "Hvor finner hendelsen sted? Hvis den ikke finnes kan du opprette den.",
- "added_anon": "Hendelse lagt til, men ikke bekreftet enda.",
- "added": "Hendelse lagt til",
- "media_description": "Du kan legge til et flygeblad (valgfritt)",
- "anon_description": "Du kan legge til en hendelse uten å registrere deg eller logge inn, og den vil bli lagt ut etter at den er bekreftet å være passende. Det vil ikke være mulig å endre den.
\nDu kan istedenfor logge inn, eller registrere deg. Ellers kan du forsette for å få et svar så snart som mulig. ",
- "ics": "ICS",
- "import_ICS": "Importer fra ICS",
- "import_URL": "Importer fra nettadresse",
- "edit_recurrent": "Rediger gjentagende hendelse",
- "updated": "Handelse oppdatert"
- },
- "register": {
- "first_user": "Administrator opprettet",
- "complete": "Registrering må bekreftes.",
- "error": "Feil: ",
- "description": "Sosiale bevegelser bør organisere og finansiere seg selv.
\n
Før du kan publisere, må kontoen godkjennes, ha i minnet at bak denne siden er det mennesker, så skriv to linjer om hvilke hendelser du ønsker å publisere."
- },
- "recover": {
- "not_valid_code": "Noe gikk galt."
- },
- "login": {
- "ok": "Innlogget",
- "forgot_password": "Glemt passordet?",
- "not_registered": "Ikke registrert?",
- "description": "Ved å logge inn kan du publisere nye hendelser.",
- "error": "Kunne ikke logge inn. Sjekk dine innloggingsdetaljer.",
- "check_email": "Sjekk din e-postinnboks og søppelpost.",
- "insert_email": "Skriv inn din e-postadresse"
- },
- "common": {
- "reset": "Tilbakestill",
- "theme": "Drakt",
- "tags": "Etiketter",
- "place": "Sted",
- "url": "Nettadresse",
- "announcements": "Kunngjøringer",
- "delete": "Fjern",
- "skip": "Hopp over",
- "fediverse": "Fediverset",
- "start": "Start",
- "pause": "Pause",
- "event": "Hendelse",
- "filter": "Filter",
- "title": "Tittel",
- "user": "Bruker",
- "moderation": "Moderering",
- "follow": "Følg",
- "follow_me_title": "Følg oppdateringer fra fediverset",
- "feed_url_copied": "Informasjonskanalsnettadresse kopiert, lim den inn i din RSS-leser",
- "feed": "RSS-informasjonskanal",
- "embed_help": "Kopiering av følgende kode til nettsiden din vil vises som her",
- "embed_title": "Bygg inn denne hendelsen på nettsiden din",
- "embed": "Innebygg",
- "copied": "Kopiert",
- "instances": "Instanser",
- "add_to_calendar": "Legg til i kalender",
- "send_via_mail": "Send e-post",
- "copy_link": "Kopier lenke",
- "set_password": "Sett passord",
- "displayname": "Visningsnavn",
- "activate_user": "Bekreftet",
- "resources": "Ressurser",
- "password_updated": "Passord endret.",
- "me": "Du",
- "disable": "Skru av",
- "enable": "Skru på",
- "cancel": "Avbryt",
- "ok": "OK",
- "new_user": "Ny bruker",
- "new_password": "Nytt passord",
- "recover_password": "Gjenopprett passord",
- "copy": "Kopier",
- "logout_ok": "Utlogget",
- "add": "Legg til",
- "related": "Relatert",
- "edit_event": "Rediger hendelse",
- "name": "Navn",
- "share": "Del",
- "logout": "Logg ut",
- "preview": "Forhåndsvis",
- "save": "Lagre",
- "activate": "Aktiver",
- "remove_admin": "Fjern administrator",
- "deactivate": "Skru av",
- "actions": "Handlinger",
- "settings": "Valg",
- "places": "Steder",
- "events": "Handelser",
- "admin": "Administrator",
- "users": "Brukere",
- "confirm": "Bekreft",
- "info": "Info",
- "edit": "Rediger",
- "search": "Søk",
- "hide": "Skjul",
- "remove": "Fjern",
- "description": "Beskrivelse",
- "register": "Registrer",
- "password": "Passord",
- "email": "E-post",
- "login": "Logg inn",
- "media": "Media",
- "what": "Hva",
- "when": "Når",
- "address": "Adresse",
- "where": "Hvor",
- "send": "Send",
- "export": "Eksporter",
- "next": "Neste",
- "add_event": "Legg til hendelse",
- "authorize": "Autoriser",
- "federation": "Føderasjon",
- "n_resources": "ingen ressurs|én ressurs|{n} ressurser",
- "associate": "Tilknytt",
- "import": "Importer"
- },
- "about": "\n Gancio er en delt agenda for lokale gemenskaper.
\n ",
- "validators": {
- "email": "Skriv inn en gyldig e-postadresse",
- "required": "{fieldName} kreves"
- },
- "ordinal": {
- "-1": "siste",
- "5": "femte",
- "4": "fjerde",
- "3": "tredje",
- "2": "andre",
- "1": "første"
- },
- "export": {
- "list_description": "Hvis du har en nettside og ønsker å vise en liste over hendelser, bruk følgende kode",
- "ical_description": "Datamaskiner og smarttelefoner er vanligvis utstyrt med et kalenderprogram som kan importere kalendere.",
- "feed_description": "For å følge oppdateringer fra en datamaskin eller smarttelefon uten å trenge å åpne denne siden, kan du bruke en RSS-leser. \n\n Med en RSS-informasjonskanal kan du bruke et egnet program for å motta oppdateringer fra sider som interesserer deg. Det er en bra måte å følge mange sider raskt, uten å måtte opprette en konto eller annet plunder.
\n\n Hvis du har Android, anbefales Flym or Feeder \n For iPhone/iPad kan du bruke Feed4U \n For skrivebord/bærbar anbefales Feedbro, installert på Firefox eller Chrome .\n
\nÅ legge denne lenken til i din RSS-leser vil holde deg oppdatert.",
- "insert_your_address": "Skriv inn din e-postadresse",
- "email_description": "Du kan få hendelser som interesserer deg tilsendt per e-post.",
- "intro": "Ulikt usosiale plattformer som gjør det de kan for å beholde brukere og data om dem, tror vi at den infoen, som folk, må ha sin frihet. Du kan holde deg oppdatert om hendelsene du ønsker, uten å nødvendigvis gå gjennom denne siden."
- }
-}
From 8ca7dc235048d4e9a6930f0da98b23682927d2ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Allan=20Nordh=C3=B8y?=
Date: Tue, 30 Mar 2021 07:39:58 +0000
Subject: [PATCH 005/113] Translated using Weblate (English)
Currently translated at 100.0% (226 of 226 strings)
Translation: Gancio/Web
Translate-URL: https://hosted.weblate.org/projects/gancio/web/en/
---
locales/en.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/locales/en.json b/locales/en.json
index cb5ca72a..96b49c13 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -91,7 +91,7 @@
"check_email": "Check your e-mail inbox and spam.",
"not_registered": "Not registered?",
"forgot_password": "Forgot your password?",
- "error": "Could not log in. Check your credentials.",
+ "error": "Could not log in. Check your login info.",
"insert_email": "Enter your e-mail address",
"ok": "Logged in"
},
From 8e2b0effa9d27affe673b0c8e1b43e11a0b639b7 Mon Sep 17 00:00:00 2001
From: lesion
Date: Tue, 30 Mar 2021 07:42:09 +0000
Subject: [PATCH 006/113] Translated using Weblate (Spanish)
Currently translated at 99.1% (224 of 226 strings)
Translation: Gancio/Web
Translate-URL: https://hosted.weblate.org/projects/gancio/web/es/
---
locales/es.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/locales/es.json b/locales/es.json
index b5b42770..d92f526c 100644
--- a/locales/es.json
+++ b/locales/es.json
@@ -123,7 +123,7 @@
"media_description": "Puedes agregar un panfleto (opcionál)",
"added": "Evento agregado",
"added_anon": "Evento agregado, será confirmado cuanto antes.",
- "where_description": "¿Dónde es? Si el lugar no está, escribilo y presiona enter. ",
+ "where_description": "¿Dónde es? Si el lugar no está, escribilo.",
"confirmed": "Evento confirmado",
"not_found": "Evento no encontrado",
"remove_confirmation": "¿Estás seguro/a de querér eliminar este evento?",
From 24170f0dfa7711402450b2dce928d2edf56fd2b2 Mon Sep 17 00:00:00 2001
From: Nathan
Date: Sun, 4 Apr 2021 17:40:48 +0000
Subject: [PATCH 007/113] Translated using Weblate (French)
Currently translated at 100.0% (226 of 226 strings)
Translation: Gancio/Web
Translate-URL: https://hosted.weblate.org/projects/gancio/web/fr/
---
locales/fr.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/locales/fr.json b/locales/fr.json
index 4fd151d4..a6e1680a 100644
--- a/locales/fr.json
+++ b/locales/fr.json
@@ -249,7 +249,7 @@
"login": {
"ok": "Connecté",
"insert_email": "Saisissez votre adresse courriel",
- "error": "Impossible de se connecter. Veuillez vérifier vos identifiants.",
+ "error": "Impossible de se connecter. Veuillez vérifier vos informations de connexion.",
"forgot_password": "Mot de passe oublié ?",
"not_registered": "Pas encore inscrit·e ?",
"check_email": "Vérifiez votre boîte de réception et les indésirables.",
From 5ac73caeace8eeedfa6a9bda518577a0f854fd15 Mon Sep 17 00:00:00 2001
From: les
Date: Fri, 9 Apr 2021 23:54:17 +0200
Subject: [PATCH 008/113] clean unused places/tags #107 and unused fields
---
server/api/controller/event.js | 42 ++++++++-----------
server/api/models/event.js | 1 +
server/api/models/place.js | 10 +----
server/api/models/tag.js | 13 ------
server/helpers/place.js | 22 ++++++++++
server/helpers/tag.js | 22 ++++++++++
.../20210409212349-remove_tag_confirmation.js | 6 +++
...0210409212803-remove_place_confirmation.js | 6 +++
.../20210409212842-remove_tag_weigth.js | 6 +++
server/taskManager.js | 3 ++
vuetify.options.js | 1 +
11 files changed, 86 insertions(+), 46 deletions(-)
create mode 100644 server/helpers/place.js
create mode 100644 server/helpers/tag.js
create mode 100644 server/migrations/20210409212349-remove_tag_confirmation.js
create mode 100644 server/migrations/20210409212803-remove_place_confirmation.js
create mode 100644 server/migrations/20210409212842-remove_tag_weigth.js
diff --git a/server/api/controller/event.js b/server/api/controller/event.js
index 481828ab..823b5ef3 100644
--- a/server/api/controller/event.js
+++ b/server/api/controller/event.js
@@ -25,23 +25,22 @@ const eventController = {
async _getMeta () {
const places = await Place.findAll({
- where: { confirmed: true },
order: [[Sequelize.literal('weigth'), 'DESC']],
attributes: {
include: [[Sequelize.fn('count', Sequelize.col('events.placeId')), 'weigth']],
exclude: ['createdAt', 'updatedAt']
},
- include: [{ model: Event, attributes: [] }],
+ include: [{ model: Event, where: { is_visible: true }, required: true, attributes: [] }],
group: ['place.id']
})
const tags = await Tag.findAll({
- where: { confirmed: true },
- raw: true,
- order: [['weigth', 'DESC']],
+ order: [[Sequelize.literal('w'), 'DESC']],
attributes: {
- exclude: ['createdAt', 'updatedAt']
- }
+ include: [[Sequelize.fn('COUNT', Sequelize.col('tag.tag')), 'w']]
+ },
+ include: [{ model: Event, where: { is_visible: true }, attributes: [], through: { attributes: [] }, required: true }],
+ group: ['tag.tag']
})
return { places, tags }
@@ -178,14 +177,6 @@ const eventController = {
try {
event.is_visible = true
- // confirm tag & place if needed
- if (!event.place.confirmed) {
- await event.place.update({ confirmed: true })
- }
-
- await Tag.update({ confirmed: true },
- { where: { confirmed: false, tag: { [Op.in]: event.tags.map(t => t.tag) } } })
-
await event.save()
res.sendStatus(200)
@@ -295,8 +286,7 @@ const eventController = {
const [place] = await Place.findOrCreate({
where: { name: body.place_name },
defaults: {
- address: body.place_address,
- confirmed: !!req.user
+ address: body.place_address
}
})
@@ -305,9 +295,8 @@ const eventController = {
// create/assign tags
if (body.tags) {
- await Tag.bulkCreate(body.tags.map(t => ({ tag: t, confirmed: !!req.user })), { ignoreDuplicates: true })
+ await Tag.bulkCreate(body.tags.map(t => ({ tag: t })), { ignoreDuplicates: true })
const tags = await Tag.findAll({ where: { tag: { [Op.in]: body.tags } } })
- await Promise.all(tags.map(t => t.update({ weigth: Number(t.weigth) + 1, confirmed: true })))
await event.addTags(tags)
event.tags = tags
}
@@ -456,14 +445,19 @@ const eventController = {
const events = await Event.findAll({
where,
attributes: {
- exclude: ['slug', 'likes', 'boost', 'userId', 'is_visible', 'createdAt', 'updatedAt', 'placeId', 'description', 'resources']
- // include: [[Sequelize.fn('COUNT', Sequelize.col('activitypub_id')), 'ressources']]
+ exclude: ['slug', 'likes', 'boost', 'userId', 'is_visible', 'createdAt', 'updatedAt', 'description', 'resources']
},
- order: ['start_datetime', [Tag, 'weigth', 'DESC']],
+ order: ['start_datetime', Sequelize.literal('(SELECT COUNT("tagTag") FROM event_tags WHERE "tagTag" = tag) DESC')],
include: [
{ model: Resource, required: false, attributes: ['id'] },
- { model: Tag, attributes: ['tag'], required: !!tags, ...where_tags, through: { attributes: [] } },
- { model: Place, required: false, attributes: ['id', 'name', 'address'] }
+ {
+ model: Tag,
+ attributes: ['tag'],
+ required: !!tags,
+ ...where_tags,
+ through: { attributes: [] }
+ },
+ { model: Place, required: true, attributes: ['id', 'name', 'address'] }
]
}).catch(e => {
log.error(e)
diff --git a/server/api/models/event.js b/server/api/models/event.js
index a59b23b3..2f04b142 100644
--- a/server/api/models/event.js
+++ b/server/api/models/event.js
@@ -51,6 +51,7 @@ Event.belongsTo(User)
User.hasMany(Event)
Event.belongsToMany(Tag, { through: 'event_tags' })
+Tag.belongsToMany(Event, { through: 'event_tags' })
Event.belongsToMany(Notification, { through: EventNotification })
Notification.belongsToMany(Event, { through: EventNotification })
diff --git a/server/api/models/place.js b/server/api/models/place.js
index 8db4e845..fac19112 100644
--- a/server/api/models/place.js
+++ b/server/api/models/place.js
@@ -1,7 +1,6 @@
const { Model, DataTypes } = require('sequelize')
const sequelize = require('./index')
-// const Event = require('./event')
class Place extends Model {}
Place.init({
@@ -11,14 +10,7 @@ Place.init({
index: true,
allowNull: false
},
- address: DataTypes.STRING,
- confirmed: {
- type: DataTypes.BOOLEAN,
- defaultValue: true,
- allowNull: false
- }
+ address: DataTypes.STRING
}, { sequelize, modelName: 'place' })
-// Place.hasMany(Event)
-
module.exports = Place
diff --git a/server/api/models/tag.js b/server/api/models/tag.js
index 7a47e7af..ec292354 100644
--- a/server/api/models/tag.js
+++ b/server/api/models/tag.js
@@ -1,5 +1,4 @@
const { Model, DataTypes } = require('sequelize')
-// const Event = require('./event')
const sequelize = require('./index')
class Tag extends Model {}
@@ -10,19 +9,7 @@ Tag.init({
allowNull: false,
index: true,
primaryKey: true
- },
- weigth: {
- type: DataTypes.INTEGER,
- defaultValue: 0,
- allowNull: false
- },
- confirmed: {
- type: DataTypes.BOOLEAN,
- defaultValue: true,
- allowNull: false
}
}, { sequelize, modelName: 'tag' })
-// Tag.belongsToMany(Event, { through: 'event_tags' })
-
module.exports = Tag
diff --git a/server/helpers/place.js b/server/helpers/place.js
new file mode 100644
index 00000000..ff87797a
--- /dev/null
+++ b/server/helpers/place.js
@@ -0,0 +1,22 @@
+const Place = require('../api/models/place')
+const Event = require('../api/models/event')
+const Sequelize = require('sequelize')
+const log = require('../log')
+
+module.exports = {
+ // remove places not related to any events
+ async _cleanUnused () {
+ const places = await Place.findAll({
+ include: [{ model: Event, as: 'events', required: false, attributes: [] }],
+ group: ['place.id'],
+ having: Sequelize.where(Sequelize.fn('COUNT', Sequelize.col('events.id')), '=', 0)
+ })
+ if (!places.length) { return }
+ log.debug(`Remove ${places.length} unrelated places`)
+
+ const ids = places.map(p => p.id)
+ await Place.destroy({
+ where: { id: { [Sequelize.Op.in]: ids } }
+ })
+ }
+}
diff --git a/server/helpers/tag.js b/server/helpers/tag.js
new file mode 100644
index 00000000..63f31627
--- /dev/null
+++ b/server/helpers/tag.js
@@ -0,0 +1,22 @@
+const Tag = require('../api/models/tag')
+const Event = require('../api/models/event')
+const Sequelize = require('sequelize')
+const log = require('../log')
+
+module.exports = {
+ // remove tags not related to any events
+ async _cleanUnused () {
+ const tags = await Tag.findAll({
+ include: [{ model: Event, as: 'events', required: false, attributes: [], through: { attributes: [] } }],
+ group: ['tag.tag'],
+ having: Sequelize.where(Sequelize.fn('COUNT', Sequelize.col('events.id')), '=', 0)
+ })
+
+ if (!tags.length) { return }
+ log.info(`Remove ${tags.length} unrelated tags`)
+
+ await Tag.destroy({
+ where: { tag: { [Sequelize.Op.in]: tags.map(p => p.tag) } }
+ })
+ }
+}
diff --git a/server/migrations/20210409212349-remove_tag_confirmation.js b/server/migrations/20210409212349-remove_tag_confirmation.js
new file mode 100644
index 00000000..ab01586e
--- /dev/null
+++ b/server/migrations/20210409212349-remove_tag_confirmation.js
@@ -0,0 +1,6 @@
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ return queryInterface.removeColumn('tags', 'confirmed')
+ }
+}
diff --git a/server/migrations/20210409212803-remove_place_confirmation.js b/server/migrations/20210409212803-remove_place_confirmation.js
new file mode 100644
index 00000000..4775b923
--- /dev/null
+++ b/server/migrations/20210409212803-remove_place_confirmation.js
@@ -0,0 +1,6 @@
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ return queryInterface.removeColumn('places', 'confirmed')
+ }
+}
diff --git a/server/migrations/20210409212842-remove_tag_weigth.js b/server/migrations/20210409212842-remove_tag_weigth.js
new file mode 100644
index 00000000..9c9e7b2d
--- /dev/null
+++ b/server/migrations/20210409212842-remove_tag_weigth.js
@@ -0,0 +1,6 @@
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ return queryInterface.removeColumn('tags', 'weigth')
+ }
+}
diff --git a/server/taskManager.js b/server/taskManager.js
index 1fc40627..18a583c8 100644
--- a/server/taskManager.js
+++ b/server/taskManager.js
@@ -1,5 +1,7 @@
const log = require('./log')
const eventController = require('./api/controller/event')
+const placeHelpers = require('./helpers/place')
+const tagHelpers = require('./helpers/tag')
// const notifier = require('./notifier')
const loopInterval = process.env.NODE_ENV === 'production' ? 15 : 1
@@ -42,6 +44,7 @@ class Task {
* - Send AP notifications
* - Create recurrent events
* - Sync AP federation profiles
+ * - Remove unused tags/places
*/
class TaskManager {
diff --git a/vuetify.options.js b/vuetify.options.js
index 983751c7..474ac8bf 100644
--- a/vuetify.options.js
+++ b/vuetify.options.js
@@ -2,6 +2,7 @@
export default {
theme: {
dark: true,
+ // theme: { disable: true },
themes: {
dark: {
primary: '#FF6E40'
From 2d34fd41a53cf943a391fb542041606679440a86 Mon Sep 17 00:00:00 2001
From: les
Date: Sat, 10 Apr 2021 00:11:16 +0200
Subject: [PATCH 009/113] refactoring taskManager
---
server/api/mail.js | 1 -
server/taskManager.js | 36 ++++++++++++++++++++++++++----------
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/server/api/mail.js b/server/api/mail.js
index 5df442bb..84c854cb 100644
--- a/server/api/mail.js
+++ b/server/api/mail.js
@@ -12,7 +12,6 @@ const mail = {
log.debug('Enqueue new email ', template, locale)
const task = new Task({
name: 'MAIL',
- removable: true,
method: mail._send,
args: [addresses, template, locals, locale]
})
diff --git a/server/taskManager.js b/server/taskManager.js
index 18a583c8..838e7f16 100644
--- a/server/taskManager.js
+++ b/server/taskManager.js
@@ -4,17 +4,17 @@ const placeHelpers = require('./helpers/place')
const tagHelpers = require('./helpers/tag')
// const notifier = require('./notifier')
-const loopInterval = process.env.NODE_ENV === 'production' ? 15 : 1
+const loopInterval = 1 // process.env.NODE_ENV === 'production' ? 1 : 1
const minute = 60 / loopInterval
const hour = minute * 60
const day = hour * 24
class Task {
- constructor ({ name, removable = false, repeatEach = 1, method, args = [] }) {
+ constructor ({ name, repeat = false, repeatDelay = 1, callAtStart = false, method, args = [] }) {
this.name = name
- this.removable = removable
- this.repeatEach = repeatEach
- this.processInNTick = repeatEach
+ this.repeat = repeat
+ this.repeatDelay = repeatDelay
+ this.processInNTick = callAtStart ? 0 : repeatDelay
this.method = method
this.args = args
}
@@ -24,7 +24,7 @@ class Task {
if (this.processInNTick > 0) {
return
}
- this.processInNTick = this.repeatEach
+ this.processInNTick = this.repeatDelay
try {
const ret = this.method.apply(this, this.args)
if (ret && typeof ret.then === 'function') {
@@ -69,7 +69,7 @@ class TaskManager {
}
add (task) {
- log.debug(`[TASK] Add ${task.name} (${task.repeatEach * this.interval} seconds)`)
+ log.debug(`[TASK] Add ${task.name} (${task.repeatDelay * this.interval} seconds)`)
this.tasks.push(task)
}
@@ -82,7 +82,7 @@ class TaskManager {
const tasks = this.tasks.map(t => t.process())
// remove removable tasks
- this.tasks = this.tasks.filter(t => !t.removable)
+ this.tasks = this.tasks.filter(t => t.repeat)
return Promise.all(tasks)
}
@@ -97,9 +97,24 @@ const TS = new TaskManager()
// create and clean recurrent events
TS.add(new Task({
- name: 'RECURRENT_EVENT',
+ name: 'CREATE_RECURRENT_EVENT',
method: eventController._createRecurrent,
- repeatEach: 10 * minute // check each 10 minutes
+ repeatDelay: hour / 2 // check each half an hour
+}))
+
+// remove unrelated places
+TS.add(new Task({
+ name: 'CLEAN_UNUSED_PLACES',
+ method: placeHelpers._cleanUnused,
+ repeatDelay: day,
+ callAtStart: true
+}))
+
+TS.add(new Task({
+ name: 'CLEAN_UNUSED_TAGS',
+ method: tagHelpers._cleanUnused,
+ repeatDelay: day,
+ callAtStart: true
}))
// daily morning notification
@@ -122,6 +137,7 @@ TS.add(new Task({
// method: places._nominatimQuery,
// repeatEach: 60
// }))
+//
// TS.start()
// TS.add(new Task({ name: 'removable #1', method: daje, args: ['removable #1'], removable: true }))
From 945b33f8bf44dfd2a74efda0674d801492bd9c57 Mon Sep 17 00:00:00 2001
From: les
Date: Sat, 10 Apr 2021 00:20:42 +0200
Subject: [PATCH 010/113] minor
---
server/api/controller/event.js | 3 ++-
server/taskManager.js | 5 ++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/server/api/controller/event.js b/server/api/controller/event.js
index 823b5ef3..727879d5 100644
--- a/server/api/controller/event.js
+++ b/server/api/controller/event.js
@@ -86,6 +86,7 @@ const eventController = {
},
async get (req, res) {
+ log.error('get')
const format = req.params.format || 'json'
const is_admin = req.user && req.user.is_admin
const id = Number(req.params.event_id)
@@ -97,7 +98,7 @@ const eventController = {
exclude: ['createdAt', 'updatedAt', 'placeId']
},
include: [
- { model: Tag, required: false, attributes: ['tag', 'weigth'], through: { attributes: [] } },
+ { model: Tag, required: false, attributes: ['tag'], through: { attributes: [] } },
{ model: Place, attributes: ['name', 'address', 'id'] },
{
model: Resource,
diff --git a/server/taskManager.js b/server/taskManager.js
index 838e7f16..c35fd627 100644
--- a/server/taskManager.js
+++ b/server/taskManager.js
@@ -99,7 +99,8 @@ const TS = new TaskManager()
TS.add(new Task({
name: 'CREATE_RECURRENT_EVENT',
method: eventController._createRecurrent,
- repeatDelay: hour / 2 // check each half an hour
+ repeatDelay: hour / 2, // check each half an hour
+ repeat: true
}))
// remove unrelated places
@@ -107,6 +108,7 @@ TS.add(new Task({
name: 'CLEAN_UNUSED_PLACES',
method: placeHelpers._cleanUnused,
repeatDelay: day,
+ repeat: true,
callAtStart: true
}))
@@ -114,6 +116,7 @@ TS.add(new Task({
name: 'CLEAN_UNUSED_TAGS',
method: tagHelpers._cleanUnused,
repeatDelay: day,
+ repeat: true,
callAtStart: true
}))
From 63673bb031625292bd178b5693d39bb3d731e7a5 Mon Sep 17 00:00:00 2001
From: les
Date: Tue, 13 Apr 2021 18:03:23 +0200
Subject: [PATCH 011/113] fix search show recurrent switch
---
components/Search.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/components/Search.vue b/components/Search.vue
index 18b716b2..d81bd3a2 100644
--- a/components/Search.vue
+++ b/components/Search.vue
@@ -2,7 +2,7 @@
v-container.pt-0.pt-md-2
v-switch.mt-0(
v-if='recurrentFilter && settings.allow_recurrent_event'
- v-model='filters.show_recurrent'
+ :value='filters.show_recurrent'
inset color='primary'
hide-details
:label="$t('event.show_recurrent')"
From af106787d5ef7dc7b50d96b724c7f56d920f278e Mon Sep 17 00:00:00 2001
From: les
Date: Tue, 13 Apr 2021 18:03:57 +0200
Subject: [PATCH 012/113] minor on select a date
---
pages/add/DateInput.vue | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/pages/add/DateInput.vue b/pages/add/DateInput.vue
index 54e1b046..de0a32bc 100644
--- a/pages/add/DateInput.vue
+++ b/pages/add/DateInput.vue
@@ -9,7 +9,6 @@
p {{$t(`event.${type}_description`)}}
v-btn-toggle.v-col-6.flex-column.flex-sm-row(v-if='type === "recurrent"' color='primary' :value='value.recurrent.frequency' @change='fq => change("frequency", fq)')
v-btn(v-for='f in frequencies' :key='f.value' :value='f.value') {{f.text}}
-
client-only
.datePicker.mt-3
v-input(:value='fromDate'
@@ -34,11 +33,14 @@
v-row.mt-3.col-md-6.mx-auto
v-col.col-12.col-sm-6
v-select(dense :label="$t('event.from')" :value='fromHour' clearable
+ :disabled='!value.from'
:rules="[$validators.required('event.from')]"
:items='hourList' @change='hr => change("fromHour", hr)')
v-col.col-12.col-sm-6
- v-select(dense :label="$t('event.due')" :value='dueHour' clearable
+ v-select(dense :label="$t('event.due')"
+ :disabled='!fromHour'
+ :value='dueHour' clearable
:items='hourList' @change='hr => change("dueHour", hr)')
//- div.col-md-12(v-if='isRecurrent')
From 1edf6b17993a594a42d259e2fa58b6e701c28b30 Mon Sep 17 00:00:00 2001
From: les
Date: Tue, 13 Apr 2021 18:04:53 +0200
Subject: [PATCH 013/113] let's slugifyyyy
---
components/Event.vue | 4 ++--
package.json | 1 +
server/api/controller/event.js | 17 +++++++++++++----
server/api/models/event.js | 10 +++++++++-
4 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/components/Event.vue b/components/Event.vue
index e8009b26..f6624ee4 100644
--- a/components/Event.vue
+++ b/components/Event.vue
@@ -1,6 +1,6 @@
v-card.h-event.event
- nuxt-link(:to='`/event/${event.id}`')
+ nuxt-link(:to='`/event/${event.slug || event.id}`')
v-img.img(:src="`/media/thumb/${event.image_path || 'logo.svg' }`")
v-icon.float-right.mr-1(v-if='event.parentId' color='success') mdi-repeat
.title.p-name {{event.title}}
@@ -43,4 +43,4 @@ export default {
},
computed: mapState(['settings'])
}
-
\ No newline at end of file
+
diff --git a/package.json b/package.json
index 5b29a195..e75dd049 100644
--- a/package.json
+++ b/package.json
@@ -67,6 +67,7 @@
"prom-client": "^13.1.0",
"sequelize": "^6.6.2",
"sequelize-cli": "^6.2.0",
+ "sequelize-slugify": "^1.5.0",
"sharp": "^0.27.2",
"sqlite3": "^5.0.2",
"tiptap": "^1.32.0",
diff --git a/server/api/controller/event.js b/server/api/controller/event.js
index 727879d5..eb95df40 100644
--- a/server/api/controller/event.js
+++ b/server/api/controller/event.js
@@ -86,14 +86,21 @@ const eventController = {
},
async get (req, res) {
- log.error('get')
const format = req.params.format || 'json'
const is_admin = req.user && req.user.is_admin
- const id = Number(req.params.event_id)
+ const slug = req.params.event_id
+ const id = Number(req.params.event_id) || -1
+ console.error(slug)
let event
try {
- event = await Event.findByPk(id, {
+ event = await Event.findOne({
+ where: {
+ [Op.or]: {
+ slug,
+ id
+ }
+ },
attributes: {
exclude: ['createdAt', 'updatedAt', 'placeId']
},
@@ -112,6 +119,7 @@ const eventController = {
order: [[Resource, 'id', 'DESC']]
})
} catch (e) {
+ console.error(e)
return res.sendStatus(400)
}
@@ -119,6 +127,7 @@ const eventController = {
return res.sendStatus(400)
}
+ console.error('diocane')
// get prev and next event
const next = await Event.findOne({
attributes: ['id'],
@@ -446,7 +455,7 @@ const eventController = {
const events = await Event.findAll({
where,
attributes: {
- exclude: ['slug', 'likes', 'boost', 'userId', 'is_visible', 'createdAt', 'updatedAt', 'description', 'resources']
+ exclude: ['likes', 'boost', 'userId', 'is_visible', 'createdAt', 'updatedAt', 'description', 'resources']
},
order: ['start_datetime', Sequelize.literal('(SELECT COUNT("tagTag") FROM event_tags WHERE "tagTag" = tag) DESC')],
include: [
diff --git a/server/api/models/event.js b/server/api/models/event.js
index 2f04b142..f1975a0c 100644
--- a/server/api/models/event.js
+++ b/server/api/models/event.js
@@ -3,6 +3,8 @@ const moment = require('dayjs')
const htmlToText = require('html-to-text')
const { Model, DataTypes } = require('sequelize')
+const SequelizeSlugify = require('sequelize-slugify')
+
const sequelize = require('./index')
const Resource = require('./resource')
@@ -26,7 +28,11 @@ Event.init({
autoIncrement: true
},
title: DataTypes.STRING,
- slug: DataTypes.STRING,
+ slug: {
+ type: DataTypes.STRING,
+ index: true,
+ unique: true
+ },
description: DataTypes.TEXT,
multidate: DataTypes.BOOLEAN,
start_datetime: {
@@ -62,6 +68,8 @@ Resource.belongsTo(Event)
Event.hasMany(Event, { as: 'child', foreignKey: 'parentId' })
Event.belongsTo(Event, { as: 'parent' })
+SequelizeSlugify.slugifyModel(Event, { source: ['title'] })
+
Event.prototype.toAPNote = function (username, locale, to = []) {
const tags = this.tags && this.tags.map(t => t.tag.replace(/[ #]/g, '_'))
const plainDescription = htmlToText.fromString(this.description && this.description.replace('\n', '').slice(0, 1000))
From 6dfa77e55ab57f26455fb35db1fc982acb032dae Mon Sep 17 00:00:00 2001
From: les
Date: Wed, 14 Apr 2021 01:30:51 +0200
Subject: [PATCH 014/113] more on slugify
---
components/List.vue | 2 +-
pages/embed/_event_id.vue | 4 ++--
pages/event/_id.vue | 6 +++---
pages/event/embedEvent.vue | 6 +++---
server/api/controller/event.js | 2 --
server/api/controller/export.js | 2 +-
server/api/models/event.js | 6 +++---
server/migrations/20210413152837-slugify.js | 18 ++++++++++++++++++
8 files changed, 31 insertions(+), 15 deletions(-)
create mode 100644 server/migrations/20210413152837-slugify.js
diff --git a/components/List.vue b/components/List.vue
index 7984c837..23be8723 100644
--- a/components/List.vue
+++ b/components/List.vue
@@ -5,7 +5,7 @@ div#list
h3(v-if='title') {{title}}
v-list-item(
target='_blank'
- :to='`/event/${event.id}`'
+ :to='`/event/${event.slug || event.id}`'
v-for='event in computedEvents'
:key='`${event.id}_${event.start_datetime}`' small)
v-list-item-content
diff --git a/pages/embed/_event_id.vue b/pages/embed/_event_id.vue
index 2a2dd42e..b1e13aa9 100644
--- a/pages/embed/_event_id.vue
+++ b/pages/embed/_event_id.vue
@@ -1,5 +1,5 @@
- nuxt-link.embed_event(:to='`/event/${id}`' target='_blank' :class='{ withImg: event.image_path }')
+ nuxt-link.embed_event(:to='`/event/${event.slug || event.id}`' target='_blank' :class='{ withImg: event.image_path }')
//- image
img.float-left(:src='`/media/thumb/${event.image_path || "logo.png"}`')
@@ -18,7 +18,7 @@ export default {
async asyncData ({ $axios, params, error, store }) {
try {
const event = await $axios.$get(`/event/${params.event_id}`)
- return { event, id: Number(params.event_id) }
+ return { event }
} catch (e) {
error({ statusCode: 404, message: 'Event not found' })
}
diff --git a/pages/event/_id.vue b/pages/event/_id.vue
index 20257fb2..5ee84705 100644
--- a/pages/event/_id.vue
+++ b/pages/event/_id.vue
@@ -54,7 +54,7 @@ v-container
template(v-slot:activator="{on, attrs} ")
v-btn.ml-2(large icon v-on='on' color='primary'
v-clipboard:success='copyLink'
- v-clipboard:copy='`${settings.baseurl}/event/${event.id}`')
+ v-clipboard:copy='`${settings.baseurl}/event/${event.slug || event.id}`')
v-icon mdi-content-copy
v-tooltip(bottom) {{$t('common.embed')}}
template(v-slot:activator="{on, attrs} ")
@@ -63,7 +63,7 @@ v-container
v-tooltip(bottom) {{$t('common.add_to_calendar')}}
template(v-slot:activator="{on, attrs} ")
v-btn.ml-2(large icon v-on='on' color='primary'
- :href='`/api/event/${event.id}.ics`')
+ :href='`/api/event/${event.slug || event.id}.ics`')
v-icon mdi-calendar-export
.p-description.text-body-1(v-if='event.image_path' v-html='event.description')
@@ -191,7 +191,7 @@ export default {
{
hid: 'og-url',
property: 'og:url',
- content: `${this.settings.baseurl}/event/${this.event.id}`
+ content: `${this.settings.baseurl}/event/${this.event.slug || this.event.id}`
},
{ property: 'og:type', content: 'event' },
{
diff --git a/pages/event/embedEvent.vue b/pages/event/embedEvent.vue
index 0b4fcb08..72429d1f 100644
--- a/pages/event/embedEvent.vue
+++ b/pages/event/embedEvent.vue
@@ -6,7 +6,7 @@ v-card
v-col.col-12
v-alert.mb-1.mt-1(type='info' show-icon) {{$t('common.embed_help')}}
v-text-field(v-model='code')
- v-btn(slot='prepend' plain text color='primary'
+ v-btn(slot='prepend' text color='primary'
v-clipboard:copy='code'
v-clipboard:success='copyLink') {{$t("common.copy")}}
v-icon.ml-1 mdi-content-copy
@@ -23,13 +23,13 @@ import { mapState } from 'vuex'
export default {
name: 'EmbedEvent',
props: {
- event: { type: Object, default: () => ({})}
+ event: { type: Object, default: () => ({}) }
},
computed: {
...mapState(['settings']),
code () {
const style = "style='border: 0; width: 100%; height: 215px;'"
- const src = `${this.settings.baseurl}/embed/${this.event.id}`
+ const src = `${this.settings.baseurl}/embed/${this.event.slug || this.event.id}`
const code = ``
return code
}
diff --git a/server/api/controller/event.js b/server/api/controller/event.js
index eb95df40..0bdb3a7f 100644
--- a/server/api/controller/event.js
+++ b/server/api/controller/event.js
@@ -90,7 +90,6 @@ const eventController = {
const is_admin = req.user && req.user.is_admin
const slug = req.params.event_id
const id = Number(req.params.event_id) || -1
- console.error(slug)
let event
try {
@@ -127,7 +126,6 @@ const eventController = {
return res.sendStatus(400)
}
- console.error('diocane')
// get prev and next event
const next = await Event.findOne({
attributes: ['id'],
diff --git a/server/api/controller/export.js b/server/api/controller/export.js
index cf6e7bc3..26e53dbc 100644
--- a/server/api/controller/export.js
+++ b/server/api/controller/export.js
@@ -72,7 +72,7 @@ const exportController = {
title: `[${req.settings.title}] ${e.title}`,
description: e.description,
location: `${e.place.name} - ${e.place.address}`,
- url: `${req.settings.baseurl}/event/${e.id}`,
+ url: `${req.settings.baseurl}/event/${e.slug || e.id}`,
alarms
}
})
diff --git a/server/api/models/event.js b/server/api/models/event.js
index f1975a0c..111347ad 100644
--- a/server/api/models/event.js
+++ b/server/api/models/event.js
@@ -1,6 +1,6 @@
const config = require('config')
const moment = require('dayjs')
-const htmlToText = require('html-to-text')
+const { htmlToText } = require('html-to-text')
const { Model, DataTypes } = require('sequelize')
const SequelizeSlugify = require('sequelize-slugify')
@@ -72,7 +72,7 @@ SequelizeSlugify.slugifyModel(Event, { source: ['title'] })
Event.prototype.toAPNote = function (username, locale, to = []) {
const tags = this.tags && this.tags.map(t => t.tag.replace(/[ #]/g, '_'))
- const plainDescription = htmlToText.fromString(this.description && this.description.replace('\n', '').slice(0, 1000))
+ const plainDescription = htmlToText(this.description && this.description.replace('\n', '').slice(0, 1000))
const content = `
${this.title}
📍 ${this.place && this.place.name}
@@ -80,7 +80,7 @@ Event.prototype.toAPNote = function (username, locale, to = []) {
${plainDescription}
- ${config.baseurl}/event/${this.id}
+ ${config.baseurl}/event/${this.slug || this.id}
${tags && tags.map(t => `#${t}`)}
`
diff --git a/server/migrations/20210413152837-slugify.js b/server/migrations/20210413152837-slugify.js
new file mode 100644
index 00000000..48ac2c26
--- /dev/null
+++ b/server/migrations/20210413152837-slugify.js
@@ -0,0 +1,18 @@
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ return queryInterface.changeColumn('events', 'slug', {
+ type: Sequelize.STRING,
+ index: true,
+ unique: true
+ })
+ },
+
+ down: async (queryInterface, Sequelize) => {
+ /**
+ * Add reverting commands here.
+ *
+ * Example:
+ * await queryInterface.dropTable('users');
+ */
+ }
+};
From 6fb73272bb5a19be75e6e406ab8991de6c19ab28 Mon Sep 17 00:00:00 2001
From: les
Date: Wed, 14 Apr 2021 01:33:01 +0200
Subject: [PATCH 015/113] fix filters on export
---
pages/export.vue | 32 ++++++++++++++++++--------------
plugins/api.js | 2 +-
2 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/pages/export.vue b/pages/export.vue
index fc7e2561..785707e1 100644
--- a/pages/export.vue
+++ b/pages/export.vue
@@ -125,27 +125,31 @@ export default {
}
if (this.filters.tags.length) {
- params.push(`tags=${this.filters.tags.map(t => t.id)}`)
+ params.push(`tags=${this.filters.tags.join(',')}`)
}
+ if (this.filters.show_recurrent) {
+ params.push('show_recurrent=true')
+ }
return ``
},
link () {
const typeMap = ['rss', 'ics', 'list']
- const tags = this.filters.tags.join(',')
- const places = this.filters.places.join(',')
- let query = ''
- if (tags || places) {
- query = '?'
- if (tags) {
- query += 'tags=' + tags
- if (places) { query += '&places=' + places }
- } else {
- query += 'places=' + places
- }
+ const params = []
+
+ if (this.filters.tags.length) {
+ params.push(`tags=${this.filters.tags.join(',')}`)
}
- return `${this.settings.baseurl}/feed/${typeMap[this.type]}${query}`
+ if (this.filters.places.length) {
+ params.push(`places=${this.filters.places.join(',')}`)
+ }
+
+ if (this.filters.show_recurrent) {
+ params.push('show_recurrent=true')
+ }
+
+ return `${this.settings.baseurl}/feed/${typeMap[this.type]}?${params.join('&')}`
},
showLink () {
return (['rss', 'ics'].includes(this.type))
@@ -158,7 +162,7 @@ export default {
start: dayjs().unix(),
places: this.filters.places,
tags: this.filters.tags,
- show_recurrent: this.filters.show_recurrent
+ show_recurrent: !!this.filters.show_recurrent
})
},
copyLink (type) {
diff --git a/plugins/api.js b/plugins/api.js
index d1b5959b..c81179a2 100644
--- a/plugins/api.js
+++ b/plugins/api.js
@@ -22,7 +22,7 @@ export default ({ $axios, store }, inject) => {
end: params.end,
places: params.places && params.places.join(','),
tags: params.tags && params.tags.join(','),
- show_recurrent: params.show_recurrent
+ show_recurrent: !!params.show_recurrent
}
})
return events.map(e => Object.freeze(e))
From 3bb73cd75707f313b5d58753c3d88783f7b117cd Mon Sep 17 00:00:00 2001
From: les
Date: Wed, 14 Apr 2021 01:35:18 +0200
Subject: [PATCH 016/113] loading on filters update
---
pages/index.vue | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/pages/index.vue b/pages/index.vue
index 0b12fae6..70c9f7e9 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -71,6 +71,13 @@ export default {
}
},
computed: mapState(['settings', 'announcements', 'filters']),
+ mounted () {
+ const tags = document.location.hash.split('#').map(tag => decodeURIComponent(tag))
+ if (tags) {
+ this.setFilters({ ...this.filters, tags })
+ this.updateEvents()
+ }
+ },
methods: {
// onIntersect (isIntersecting, eventId) {
// this.intersecting[eventId] = isIntersecting
@@ -95,8 +102,9 @@ export default {
this.updateEvents()
},
tagClick (tag) {
+ this.$nuxt.$loading.start()
+ this.$router.push(`#${tag}`)
if (this.filters.tags.includes(tag)) {
- this.filters.tags = this.filters.tags.filter(t => t !== tag)
this.setFilters({ ...this.filters, tags: this.filters.tags.filter(t => t !== tag) })
} else {
this.setFilters({ ...this.filters, tags: [].concat(this.filters.tags, tag) })
@@ -124,15 +132,17 @@ export default {
this.updateEvents()
},
updateFilters (filters) {
+ this.$nuxt.$loading.start()
this.setFilters(filters)
this.updateEvents()
},
dayChange (day) {
+ this.$nuxt.$loading.start()
const date = dayjs(day.date).format('YYYY-MM-DD')
if (this.selectedDay === date) {
this.selectedDay = null
- this.start = dayjs().unix() // .startOf('week').unix()
- this.end = null
+ this.start = dayjs(day.date).startOf('month').unix() // .startOf('week').unix()
+ this.end = dayjs(day.date).endOf('month').unix()
this.updateEvents()
return
}
From ddd0e6d144fe6e14e0d05c80da8f3576de645675 Mon Sep 17 00:00:00 2001
From: les
Date: Wed, 21 Apr 2021 11:42:03 +0200
Subject: [PATCH 017/113] fix validation on unselect date
---
pages/add/DateInput.vue | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/pages/add/DateInput.vue b/pages/add/DateInput.vue
index de0a32bc..e5d39b4a 100644
--- a/pages/add/DateInput.vue
+++ b/pages/add/DateInput.vue
@@ -222,6 +222,10 @@ export default {
this.$emit('input', { ...this.value, dueHour: false })
}
} else if (what === 'date') {
+ if (value === null) {
+ this.$emit('input', { ...this.value, from: null, fromHour: false })
+ return
+ }
if (this.value.multidate) {
let from = value.start
let due = value.end
From fe97dda295eecf24dc7ead4ac9edbc6f4dbd309c Mon Sep 17 00:00:00 2001
From: les
Date: Mon, 26 Apr 2021 11:25:35 +0200
Subject: [PATCH 018/113] create instance in any case
---
server/federation/helpers.js | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/server/federation/helpers.js b/server/federation/helpers.js
index 38b02c2f..5fae81ea 100644
--- a/server/federation/helpers.js
+++ b/server/federation/helpers.js
@@ -27,7 +27,6 @@ const Helpers = {
]
if (urlToIgnore.includes(req.path)) {
log.debug(`Ignore noisy fediverse ${req.path}`)
- log.debug(req)
return res.status(404).send('Not Found')
}
next()
@@ -161,16 +160,17 @@ const Helpers = {
})
.catch(e => {
log.error(e)
- return false
+ return Instance.create({ name: domain, domain, blocked: false })
})
return instance
},
// ref: https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/
async verifySignature (req, res, next) {
+ // TODO: why do I need instance?
const instance = await Helpers.getInstance(req.body.actor)
if (!instance) {
- log.warn(`[AP] Verify Signature: Instance not found ${req.body.actor}`)
+ log.warn(`Verify Signature: Instance not found ${req.body.actor}`)
return res.status(401).send('Instance not found')
}
if (instance.blocked) {
@@ -188,11 +188,17 @@ const Helpers = {
return res.status(401).send('User blocked')
}
- // little hack -> https://github.com/joyent/node-http-signature/pull/83
- // req.headers.authorization = 'Signature ' + req.headers.signature
-
req.fedi_user = user
+ // TODO: check Digest // cannot do this with json bodyparser
+ // const digest = crypto.createHash('sha256')
+ // .update(req.body)
+ // .digest('base64')
+ // if (`SHA-256=${digest}` !== req.headers.signature) {
+ // log.warning(`Signature mismatch ${req.headers.signature} - ${digest}`)
+ // return res.status(401).send('Signature mismatch')
+ // }
+
// another little hack :/
// https://github.com/joyent/node-http-signature/issues/87
req.url = '/federation' + req.url
From 691684d9dce0d393d1c3be4afc33996122760e11 Mon Sep 17 00:00:00 2001
From: les
Date: Mon, 26 Apr 2021 11:26:59 +0200
Subject: [PATCH 019/113] get all instances for admin in correct order
---
server/api/controller/instance.js | 13 ++++++++++---
server/federation/ego.js | 2 ++
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/server/api/controller/instance.js b/server/api/controller/instance.js
index b81388ba..2cea4141 100644
--- a/server/api/controller/instance.js
+++ b/server/api/controller/instance.js
@@ -1,12 +1,19 @@
const APUser = require('../models/ap_user')
const Instance = require('../models/instance')
const Resource = require('../models/resource')
-
-// const { Op } = require('sequelize')
+const Sequelize = require('sequelize')
const instancesController = {
async getAll (req, res) {
- const instances = await Instance.findAll({ raw: true })
+ const instances = await Instance.findAll({
+ attributes: [
+ 'domain', 'name', 'data', 'blocked',
+ [Sequelize.fn('COUNT', Sequelize.col('ap_users.ap_id')), 'users']
+ ],
+ order: [[Sequelize.fn('COUNT', Sequelize.col('ap_users.ap_id')), 'DESC']],
+ group: ['instance.domain'],
+ include: [{ model: APUser, attributes: [] }]
+ })
return res.json(instances)
},
diff --git a/server/federation/ego.js b/server/federation/ego.js
index b8d57aa3..f1be8dac 100644
--- a/server/federation/ego.js
+++ b/server/federation/ego.js
@@ -9,6 +9,7 @@ module.exports = {
log.debug(`boost ${match[1]}`)
const event = await Event.findByPk(Number(match[1]))
if (!event) { return res.status(404).send('Event not found!') }
+ // TODO, has to be unique...
await event.update({ boost: [...event.boost, req.body.actor] })
res.sendStatus(201)
},
@@ -28,6 +29,7 @@ module.exports = {
const event = await Event.findByPk(Number(match[1]))
log.debug(`${req.body.actor} bookmark ${event.title} (${event.likes.length})`)
if (!event) { return res.status(404).send('Event not found!') }
+ // TODO: has to be unique
await event.update({ likes: [...event.likes, req.body.actor] })
res.sendStatus(201)
},
From 1ccf0397c51c88b77317ada474415968432b03f6 Mon Sep 17 00:00:00 2001
From: les
Date: Mon, 26 Apr 2021 11:27:14 +0200
Subject: [PATCH 020/113] return slug in next/prev calculation
---
server/api/controller/event.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/server/api/controller/event.js b/server/api/controller/event.js
index 0bdb3a7f..6272df08 100644
--- a/server/api/controller/event.js
+++ b/server/api/controller/event.js
@@ -128,7 +128,7 @@ const eventController = {
// get prev and next event
const next = await Event.findOne({
- attributes: ['id'],
+ attributes: ['id', 'slug'],
where: {
is_visible: true,
recurrent: null,
@@ -138,7 +138,7 @@ const eventController = {
})
const prev = await Event.findOne({
- attributes: ['id'],
+ attributes: ['id', 'slug'],
where: {
is_visible: true,
recurrent: null,
@@ -149,8 +149,8 @@ const eventController = {
if (event && (event.is_visible || is_admin)) {
event = event.get()
- event.next = next && next.id
- event.prev = prev && prev.id
+ event.next = next && (next.slug || next.id)
+ event.prev = prev && (prev.slug || prev.id)
event.tags = event.tags.map(t => t.tag)
if (format === 'json') {
res.json(event)
@@ -360,8 +360,8 @@ const eventController = {
const old_path = path.resolve(config.upload_path, event.image_path)
const old_thumb_path = path.resolve(config.upload_path, 'thumb', event.image_path)
try {
- await fs.unlinkSync(old_path)
- await fs.unlinkSync(old_thumb_path)
+ fs.unlinkSync(old_path)
+ fs.unlinkSync(old_thumb_path)
} catch (e) {
log.info(e.toString())
}
From 5fb1b9b98375f4986966511157f55ee1a815e22a Mon Sep 17 00:00:00 2001
From: les
Date: Mon, 26 Apr 2021 23:13:37 +0200
Subject: [PATCH 021/113] improve moderation ux
---
components/admin/Moderation.vue | 27 ++++++++-------------------
1 file changed, 8 insertions(+), 19 deletions(-)
diff --git a/components/admin/Moderation.vue b/components/admin/Moderation.vue
index 43395afe..7a567478 100644
--- a/components/admin/Moderation.vue
+++ b/components/admin/Moderation.vue
@@ -11,21 +11,9 @@
:hide-default-footer='instances.length<5'
dense :headers='instancesHeader'
@click:row='instanceSelected')
- //- el-table-column(label='Domain' width='180')
- //- template(slot-scope='data')
- //- span(slot='reference') {{data.row.domain}}
- //- el-table-column(label='Name' width='100')
- //- template(slot-scope='data')
- //- span(slot='reference') {{data.row.name}}
- //- el-table-column(:label="$t('common.users')" width='70')
- //- template(slot-scope='data')
- //- span(slot='reference') {{data.row.users}}
- //- el-table-column(:label="$t('common.actions')" width='120')
- //- template(slot-scope='data')
- //- el-button-group
- //- el-button(size='mini'
- //- :type='data.row.blocked?"danger":"warning"'
- //- @click='toggleBlock(data.row)') {{data.row.blocked?$t('admin.unblock'):$t('admin.block')}}
+ template(v-slot:item.blocked="{ item }")
+ v-icon(v-if='item.blocked') mdi-checkbox-intermediate
+ v-icon(v-else) mdi-checkbox-blank-outline
v-col(:span='11')
span {{$t('common.users')}}
@@ -34,8 +22,8 @@
:items-per-page='5'
:hide-default-footer='users.length<5'
dense :headers='usersHeader')
- template(v-slot:item.username="{item}")
- a(:href='item.ap_id') {{item.object.preferredUsername}}
+ //- template(v-slot:item.username="{item}")
+ //- a(:href='item.ap_id') {{item.object.preferredUsername}}
//- el-table-column(:label="$t('common.user')" width='150')
//- template(slot-scope='data')
//- span(slot='reference')
@@ -86,12 +74,13 @@ export default {
resources: [],
users: [],
usersHeader: [
- { value: 'username', text: 'Name' }
+ { value: 'object.preferredUsername', text: 'Name' }
],
instancesHeader: [
{ value: 'domain', text: 'Domain' },
{ value: 'name', text: 'Name' },
- { value: 'users', text: 'N' }
+ { value: 'blocked', text: 'Blocked' },
+ { value: 'users', text: 'known users' }
],
resourcesHeader: [
{ value: '', text: '' }
From 0cbd419210cf404a55954c6352ff64716f42d4fa Mon Sep 17 00:00:00 2001
From: les
Date: Mon, 26 Apr 2021 23:13:59 +0200
Subject: [PATCH 022/113] past dot opacity
---
assets/helper.js | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/assets/helper.js b/assets/helper.js
index 8c0ed801..11640c34 100644
--- a/assets/helper.js
+++ b/assets/helper.js
@@ -1,19 +1,23 @@
import take from 'lodash/take'
import get from 'lodash/get'
+import dayjs from 'dayjs'
export function attributesFromEvents (_events, _tags) {
const colors = ['blue', 'orange', 'yellow', 'teal', 'indigo', 'green', 'red', 'purple', 'pink', 'gray']
const tags = take(_tags, 10).map(t => t.tag)
let attributes = []
attributes.push({ key: 'today', dates: new Date(), highlight: { color: 'green', fillMode: 'outline' } })
+ const now = dayjs().unix()
function getColor (event) {
const color = { class: 'vc-rounded-full', color: 'blue', fillMode: 'normal' }
const tag = get(event, 'tags[0]')
+ if (event.start_datetime < now) { color.class += ' vc-past' }
if (!tag) { return color }
const idx = tags.indexOf(tag)
if (idx < 0) { return color }
color.color = colors[idx]
+ if (event.start_datetime < now) { color.class += ' vc-past' }
return color
}
From 8519b26c05edec695a95ba684e855e130d60250d Mon Sep 17 00:00:00 2001
From: les
Date: Mon, 26 Apr 2021 23:18:16 +0200
Subject: [PATCH 023/113] minor
---
components/Event.vue | 2 +-
components/Footer.vue | 2 +-
components/admin/Announcement.vue | 6 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/components/Event.vue b/components/Event.vue
index f6624ee4..ab8181d7 100644
--- a/components/Event.vue
+++ b/components/Event.vue
@@ -1,5 +1,5 @@
- v-card.h-event.event
+ v-card.h-event.event.d-flex
nuxt-link(:to='`/event/${event.slug || event.id}`')
v-img.img(:src="`/media/thumb/${event.image_path || 'logo.svg' }`")
v-icon.float-right.mr-1(v-if='event.parentId' color='success') mdi-repeat
diff --git a/components/Footer.vue b/components/Footer.vue
index 873cd5ca..ff088caa 100644
--- a/components/Footer.vue
+++ b/components/Footer.vue
@@ -2,7 +2,7 @@
v-footer(color='secondary')
v-btn(color='primary' text href='https://gancio.org') Gancio {{settings.version}}
v-btn(v-for='link in settings.footerLinks'
- :key='link.label' color='primary' text :href='link.href') {{link.label}}
+ :key='link.label' color='primary' text :to='link.href') {{link.label}}
v-menu(v-if='settings.enable_trusted_instances && settings.trusted_instances && settings.trusted_instances.length'
offset-y bottom open-on-hover transition="slide-y-transition")
diff --git a/components/admin/Announcement.vue b/components/admin/Announcement.vue
index b3f4ffde..1ca0cf38 100644
--- a/components/admin/Announcement.vue
+++ b/components/admin/Announcement.vue
@@ -5,10 +5,10 @@
v-dialog(v-model='dialog' width='800px')
v-card
v-card-title {{$t('admin.new_announcement')}}
- v-card-text
+ v-card-text.px-0
v-form(v-model='valid' ref='announcement' @submit.prevent='save')
- v-text-field(v-model='announcement.title' :label='$t("common.title")')
- Editor.mt-2(v-model='announcement.announcement'
+ v-text-field.col-12(v-model='announcement.title' :label='$t("common.title")')
+ Editor.col-12(v-model='announcement.announcement'
border no-save max-height='400px' :placeholder="$t('common.description')")
v-card-actions
v-spacer
From 486d4300df5f1f97824da71d46e0038bbf46373d Mon Sep 17 00:00:00 2001
From: les
Date: Mon, 26 Apr 2021 23:18:50 +0200
Subject: [PATCH 024/113] improve event home filters
---
assets/style.less | 24 +++++++++++---
pages/index.vue | 80 +++++++++++++++++++++++++++++++----------------
2 files changed, 73 insertions(+), 31 deletions(-)
diff --git a/assets/style.less b/assets/style.less
index ff847188..fce11976 100644
--- a/assets/style.less
+++ b/assets/style.less
@@ -54,22 +54,24 @@ li {
position: relative;
flex-direction: column;
width: 330px;
- max-width: 500px;
+ max-width: 500px !important;
flex-grow: 1;
margin-top: .4em;
margin-right: .4em;
+ transition: all .5s;
overflow: hidden;
.title {
+ transition: all .5s;
display: block;
max-height: 3.3em;
+ color: white;
overflow: hidden;
margin: 0.5rem 1rem 0.5rem 1rem;
// color: white;
- border-bottom: 1px solid rgba(4,4,4,0.2);
- font-size: 1.2em !important;
+ // border-bottom: 1px solid rgba(4,4,4,0.2);
+ font-size: 1.1em !important;
line-height: 1.1em;
- font-weight: 500;
}
.body {
@@ -79,6 +81,8 @@ li {
.img {
width: 100%;
max-height: 250px;
+ min-height: 160px;
+ background-color: #222;
object-fit: cover;
object-position: top;
}
@@ -95,4 +99,16 @@ li {
a {
text-decoration: none;
}
+}
+
+.v-list {
+ background-color: #333 !important;
+}
+
+.vc-past {
+ opacity: 0.4;
+}
+
+#event {
+ max-width: 1200px;
}
\ No newline at end of file
diff --git a/pages/index.vue b/pages/index.vue
index 70c9f7e9..413c1048 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -11,7 +11,7 @@
//- this is needed as v-calendar does not support SSR
//- https://github.com/nathanreyes/v-calendar/issues/336
client-only
- Calendar(@dayclick='dayChange' @monthchange='monthChange' :events='events')
+ Calendar(@dayclick='dayChange' @monthchange='monthChange' :events='filteredEvents')
.col.pt-0.pt-md-2
Search(:filters='filters' @update='updateFilters')
@@ -20,12 +20,13 @@
//- Events
#events.mt-1
//- div.event(v-for='(event, idx) in events' :key='event.id' v-intersect="(entries, observer, isIntersecting) => intersecting[event.id] = isIntersecting")
- Event(:event='event' v-for='(event, idx) in events' :key='event.id' @tagclick='tagClick' @placeclick='placeClick')
+ Event(:event='event' v-for='(event, idx) in visibleEvents' :key='event.id' @tagclick='tagClick' @placeclick='placeClick')