Merge branch 'master' into dev

This commit is contained in:
lesion 2023-11-05 22:23:14 +01:00
commit 19eab92d39
No known key found for this signature in database
GPG key ID: 352918250B012177
86 changed files with 5538 additions and 3842 deletions

2
.gitmodules vendored
View file

@ -1,3 +1,3 @@
[submodule "gancio_plugins/gancio-plugin-telegram-bridge"] [submodule "gancio_plugins/gancio-plugin-telegram-bridge"]
path = gancio_plugins/gancio-plugin-telegram-bridge path = gancio_plugins/gancio-plugin-telegram-bridge
url = https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge.git url = https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge

View file

@ -1,4 +1,56 @@
All notable changes to this project will be documented in this file. # Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [1.6.19](https://framagit.org/les/gancio/compare/v1.6.18...v1.6.19) (2023-11-04)
### Bug Fixes
* issue displaying recurrent event string ([a94ccda](https://framagit.org/les/gancio/commit/a94ccda049f7571a9caa90507141a0aac30331a9))
### 1.6.18 - 3 Nov '23
- [feat] allow to specify password while create new user via CLI to [support yunohost](https://github.com/YunoHost-Apps/gancio_ynh/pull/2#discussion_r1364285417)
- [feat] check if I'm reachable to myself to help in [#298](https://framagit.org/les/gancio/-/issues/298)
- [feat] improve recover and user_confirm error messages
- [feat] improve export and allow to export `collections` in rss/ics/widget
- [fix] fix postgres image version in docker-compose [#303](https://framagit.org/les/gancio/-/issues/303)
- [fix] Improve json-ld representation of events [#33](https://framagit.org/les/gancio/-/merge_requests/33)
- [fix] Add description field to admin's new user form, closes [#307](https://framagit.org/les/gancio/-/issues/307)
- [fix] use tls SSLv3 to send email, fix [#192](https://framagit.org/les/gancio/-/issues/192)
- [fix] notify user when accepted, fix [#308](https://framagit.org/les/gancio/-/issues/308)
- [fix] forgot password on active user only
- [fix] make search case insensitive, fix [#301](https://framagit.org/les/gancio/-/issues/301)
### 1.6.17 - 4 Oct '23
- [fix] typo
### 1.6.16 - 4 Oct '23
- [feat] add Czech locale
- [fix] improve datetime validation
### 1.6.15 - 3 Oct '23
- [feat] clone event
- [feat] am/pm / 24hr support, fix [#294](https://framagit.org/les/gancio/-/issues/294) [#264](https://framagit.org/les/gancio/-/issues/264)
- [feat] update telegram plugin bridge to v1.0.3, [#299](https://framagit.org/les/gancio/-/issues/299)
- [feat] include Brazilian Portuguese (pt-br) and Portugual Portuguese (pt-pt) [#292](https://framagit.org/les/gancio/-/issues/292)
- [fix] MariaDB JSON fields manual fix
- [fix] improve some corner case with SMTP From field [#297](https://framagit.org/les/gancio/-/issues/297)
- [fix] CLI has to fail when configuration not present [#284](https://framagit.org/les/gancio/-/issues/284)
- [minor] remove html2text dep from client
- [minor] RSS item's title format is now YYYY-MM-DD, [#300](https://framagit.org/les/gancio/-/issues/300)
### 1.6.14 - 30 June '23
- improve CLI accounts operations ([documentation](https://gancio.org/usage/cli))
- allow plugins to expose API ([documentation](http://gancio.org/dev/plugins))
- allow plugins to access DB ([documentation](http://gancio.org/dev/plugins))
- show map on the places page, #276 #30
- add node v18 support, #278
- fix media update, #285
- fix nodejs v14 compatibility in export
- fix invalid event microdata, #277
- fix recurrent event, #280
- update deps and locales
### 1.6.13 - 16 may '23 ### 1.6.13 - 16 may '23
- fix feed, ics, json exports - fix feed, ics, json exports

View file

@ -25,10 +25,10 @@ function ye(t) {
function u(t, e) { function u(t, e) {
t.appendChild(e); t.appendChild(e);
} }
function p(t, e, i) { function k(t, e, i) {
t.insertBefore(e, i || null); t.insertBefore(e, i || null);
} }
function k(t) { function x(t) {
t.parentNode.removeChild(t); t.parentNode.removeChild(t);
} }
function be(t, e) { function be(t, e) {
@ -38,14 +38,14 @@ function be(t, e) {
function m(t) { function m(t) {
return document.createElement(t); return document.createElement(t);
} }
function $(t) { function z(t) {
return document.createTextNode(t); return document.createTextNode(t);
} }
function M() { function C() {
return $(" "); return z(" ");
} }
function pe() { function pe() {
return $(""); return z("");
} }
function a(t, e, i) { function a(t, e, i) {
i == null ? t.removeAttribute(e) : t.getAttribute(e) !== i && t.setAttribute(e, i); i == null ? t.removeAttribute(e) : t.getAttribute(e) !== i && t.setAttribute(e, i);
@ -69,25 +69,25 @@ let O;
function I(t) { function I(t) {
O = t; O = t;
} }
function $e() { function Ee() {
if (!O) if (!O)
throw new Error("Function called outside component initialization"); throw new Error("Function called outside component initialization");
return O; return O;
} }
function ke(t) { function ke(t) {
$e().$$.on_mount.push(t); Ee().$$.on_mount.push(t);
} }
const R = [], Z = [], P = [], ee = [], Ee = Promise.resolve(); const R = [], Z = [], P = [], ee = [], $e = Promise.resolve();
let K = !1; let K = !1;
function je() { function je() {
K || (K = !0, Ee.then(x)); K || (K = !0, $e.then(y));
} }
function Q(t) { function Q(t) {
P.push(t); P.push(t);
} }
const J = /* @__PURE__ */ new Set(); const J = /* @__PURE__ */ new Set();
let D = 0; let D = 0;
function x() { function y() {
const t = O; const t = O;
do { do {
for (; D < R.length; ) { for (; D < R.length; ) {
@ -120,8 +120,8 @@ function Ce(t, e) {
function Ae(t, e, i, l) { function Ae(t, e, i, l) {
const { fragment: n, on_mount: r, on_destroy: o, after_update: f } = t.$$; const { fragment: n, on_mount: r, on_destroy: o, after_update: f } = t.$$;
n && n.m(e, i), l || Q(() => { n && n.m(e, i), l || Q(() => {
const c = r.map(W).filter(ge); const s = r.map(W).filter(ge);
o ? o.push(...c) : U(c), t.$$.on_mount = []; o ? o.push(...s) : U(s), t.$$.on_mount = [];
}), f.forEach(Q); }), f.forEach(Q);
} }
function Me(t, e) { function Me(t, e) {
@ -132,9 +132,9 @@ function Ne(t, e) {
t.$$.dirty[0] === -1 && (R.push(t), je(), t.$$.dirty.fill(0)), t.$$.dirty[e / 31 | 0] |= 1 << e % 31; t.$$.dirty[0] === -1 && (R.push(t), je(), t.$$.dirty.fill(0)), t.$$.dirty[e / 31 | 0] |= 1 << e % 31;
} }
function we(t, e, i, l, n, r, o, f = [-1]) { function we(t, e, i, l, n, r, o, f = [-1]) {
const c = O; const s = O;
I(t); I(t);
const s = t.$$ = { const c = t.$$ = {
fragment: null, fragment: null,
ctx: null, ctx: null,
props: r, props: r,
@ -146,26 +146,26 @@ function we(t, e, i, l, n, r, o, f = [-1]) {
on_disconnect: [], on_disconnect: [],
before_update: [], before_update: [],
after_update: [], after_update: [],
context: new Map(e.context || (c ? c.$$.context : [])), context: new Map(e.context || (s ? s.$$.context : [])),
callbacks: Y(), callbacks: Y(),
dirty: f, dirty: f,
skip_bound: !1, skip_bound: !1,
root: e.target || c.$$.root root: e.target || s.$$.root
}; };
o && o(s.root); o && o(c.root);
let w = !1; let w = !1;
if (s.ctx = i ? i(t, e.props || {}, (g, _, ...A) => { if (c.ctx = i ? i(t, e.props || {}, (g, _, ...A) => {
const y = A.length ? A[0] : _; const E = A.length ? A[0] : _;
return s.ctx && n(s.ctx[g], s.ctx[g] = y) && (!s.skip_bound && s.bound[g] && s.bound[g](y), w && Ne(t, g)), _; return c.ctx && n(c.ctx[g], c.ctx[g] = E) && (!c.skip_bound && c.bound[g] && c.bound[g](E), w && Ne(t, g)), _;
}) : [], s.update(), w = !0, U(s.before_update), s.fragment = l ? l(s.ctx) : !1, e.target) { }) : [], c.update(), w = !0, U(c.before_update), c.fragment = l ? l(c.ctx) : !1, e.target) {
if (e.hydrate) { if (e.hydrate) {
const g = xe(e.target); const g = xe(e.target);
s.fragment && s.fragment.l(g), g.forEach(k); c.fragment && c.fragment.l(g), g.forEach(x);
} else } else
s.fragment && s.fragment.c(); c.fragment && c.fragment.c();
e.intro && Ce(t.$$.fragment), Ae(t, e.target, e.anchor, e.customElement), x(); e.intro && Ce(t.$$.fragment), Ae(t, e.target, e.anchor, e.customElement), y();
} }
I(c); I(s);
} }
let X; let X;
typeof HTMLElement == "function" && (X = class extends HTMLElement { typeof HTMLElement == "function" && (X = class extends HTMLElement {
@ -213,11 +213,11 @@ function V(t) {
} }
function te(t, e, i) { function te(t, e, i) {
const l = t.slice(); const l = t.slice();
return l[12] = e[i], l; return l[13] = e[i], l;
} }
function ie(t, e, i) { function ie(t, e, i) {
const l = t.slice(); const l = t.slice();
return l[15] = e[i], l; return l[16] = e[i], l;
} }
function le(t) { function le(t) {
let e; let e;
@ -226,13 +226,13 @@ function le(t) {
e = m("link"), a(e, "rel", "stylesheet"), a(e, "href", t[4]); e = m("link"), a(e, "rel", "stylesheet"), a(e, "href", t[4]);
}, },
m(i, l) { m(i, l) {
p(i, e, l); k(i, e, l);
}, },
p(i, l) { p(i, l) {
l & 16 && a(e, "href", i[4]); l & 16 && a(e, "href", i[4]);
}, },
d(i) { d(i) {
i && k(e); i && x(e);
} }
}; };
} }
@ -242,32 +242,32 @@ function ne(t) {
r[o] = fe(te(t, n, o)); r[o] = fe(te(t, n, o));
return { return {
c() { c() {
e = m("div"), l && l.c(), i = M(); e = m("div"), l && l.c(), i = C();
for (let o = 0; o < r.length; o += 1) for (let o = 0; o < r.length; o += 1)
r[o].c(); r[o].c();
a(e, "id", "gancioEvents"), L(e, "dark", t[2] === "dark"), L(e, "light", t[2] === "light"), L(e, "sidebar", t[3] === "true"), L(e, "nosidebar", t[3] !== "true"); a(e, "id", "gancioEvents"), L(e, "dark", t[2] === "dark"), L(e, "light", t[2] === "light"), L(e, "sidebar", t[3] === "true"), L(e, "nosidebar", t[3] !== "true");
}, },
m(o, f) { m(o, f) {
p(o, e, f), l && l.m(e, null), u(e, i); k(o, e, f), l && l.m(e, null), u(e, i);
for (let c = 0; c < r.length; c += 1) for (let s = 0; s < r.length; s += 1)
r[c].m(e, null); r[s].m(e, null);
}, },
p(o, f) { p(o, f) {
if (o[1] && o[3] === "true" ? l ? l.p(o, f) : (l = re(o), l.c(), l.m(e, i)) : l && (l.d(1), l = null), f & 41) { if (o[1] && o[3] === "true" ? l ? l.p(o, f) : (l = re(o), l.c(), l.m(e, i)) : l && (l.d(1), l = null), f & 41) {
n = o[5]; n = o[5];
let c; let s;
for (c = 0; c < n.length; c += 1) { for (s = 0; s < n.length; s += 1) {
const s = te(o, n, c); const c = te(o, n, s);
r[c] ? r[c].p(s, f) : (r[c] = fe(s), r[c].c(), r[c].m(e, null)); r[s] ? r[s].p(c, f) : (r[s] = fe(c), r[s].c(), r[s].m(e, null));
} }
for (; c < r.length; c += 1) for (; s < r.length; s += 1)
r[c].d(1); r[s].d(1);
r.length = n.length; r.length = n.length;
} }
f & 4 && L(e, "dark", o[2] === "dark"), f & 4 && L(e, "light", o[2] === "light"), f & 8 && L(e, "sidebar", o[3] === "true"), f & 8 && L(e, "nosidebar", o[3] !== "true"); f & 4 && L(e, "dark", o[2] === "dark"), f & 4 && L(e, "light", o[2] === "light"), f & 8 && L(e, "sidebar", o[3] === "true"), f & 8 && L(e, "nosidebar", o[3] !== "true");
}, },
d(o) { d(o) {
o && k(e), l && l.d(), be(r, o); o && x(e), l && l.d(), be(r, o);
} }
}; };
} }
@ -275,23 +275,23 @@ function re(t) {
let e, i, l, n, r, o, f; let e, i, l, n, r, o, f;
return { return {
c() { c() {
e = m("a"), i = m("div"), l = m("div"), n = $(t[1]), r = M(), o = m("img"), a(l, "class", "title"), a(o, "id", "logo"), a(o, "alt", "logo"), H(o.src, f = t[0] + "/logo.png") || a(o, "src", f), a(i, "class", "content"), a(e, "href", t[0]), a(e, "target", "_blank"), a(e, "id", "header"); e = m("a"), i = m("div"), l = m("div"), n = z(t[1]), r = C(), o = m("img"), a(l, "class", "title"), a(o, "id", "logo"), a(o, "alt", "logo"), H(o.src, f = t[0] + "/logo.png") || a(o, "src", f), a(i, "class", "content"), a(e, "href", t[0]), a(e, "target", "_blank"), a(e, "id", "header");
}, },
m(c, s) { m(s, c) {
p(c, e, s), u(e, i), u(i, l), u(l, n), u(i, r), u(i, o); k(s, e, c), u(e, i), u(i, l), u(l, n), u(i, r), u(i, o);
}, },
p(c, s) { p(s, c) {
s & 2 && T(n, c[1]), s & 1 && !H(o.src, f = c[0] + "/logo.png") && a(o, "src", f), s & 1 && a(e, "href", c[0]); c & 2 && T(n, s[1]), c & 1 && !H(o.src, f = s[0] + "/logo.png") && a(o, "src", f), c & 1 && a(e, "href", s[0]);
}, },
d(c) { d(s) {
c && k(e); s && x(e);
} }
}; };
} }
function oe(t) { function oe(t) {
let e; let e;
function i(r, o) { function i(r, o) {
return r[12].media.length ? Le : Te; return r[13].media.length ? Le : Te;
} }
let l = i(t), n = l(t); let l = i(t), n = l(t);
return { return {
@ -299,13 +299,13 @@ function oe(t) {
e = m("div"), n.c(), a(e, "class", "img"); e = m("div"), n.c(), a(e, "class", "img");
}, },
m(r, o) { m(r, o) {
p(r, e, o), n.m(e, null); k(r, e, o), n.m(e, null);
}, },
p(r, o) { p(r, o) {
l === (l = i(r)) && n ? n.p(r, o) : (n.d(1), n = l(r), n && (n.c(), n.m(e, null))); l === (l = i(r)) && n ? n.p(r, o) : (n.d(1), n = l(r), n && (n.c(), n.m(e, null)));
}, },
d(r) { d(r) {
r && k(e), n.d(); r && x(e), n.d();
} }
}; };
} }
@ -313,16 +313,16 @@ function Te(t) {
let e, i, l; let e, i, l;
return { return {
c() { c() {
e = m("img"), a(e, "style", "aspect-ratio=1.7778;"), a(e, "alt", i = t[12].title), H(e.src, l = t[0] + "/fallbackimage.png") || a(e, "src", l), a(e, "loading", "lazy"); e = m("img"), a(e, "style", "aspect-ratio=1.7778;"), a(e, "alt", i = t[13].title), H(e.src, l = t[0] + "/fallbackimage.png") || a(e, "src", l), a(e, "loading", "lazy");
}, },
m(n, r) { m(n, r) {
p(n, e, r); k(n, e, r);
}, },
p(n, r) { p(n, r) {
r & 32 && i !== (i = n[12].title) && a(e, "alt", i), r & 1 && !H(e.src, l = n[0] + "/fallbackimage.png") && a(e, "src", l); r & 32 && i !== (i = n[13].title) && a(e, "alt", i), r & 1 && !H(e.src, l = n[0] + "/fallbackimage.png") && a(e, "src", l);
}, },
d(n) { d(n) {
n && k(e); n && x(e);
} }
}; };
} }
@ -330,38 +330,38 @@ function Le(t) {
let e, i, l, n; let e, i, l, n;
return { return {
c() { c() {
e = m("img"), a(e, "style", i = "object-position: " + ue(t[12]) + "; aspect-ratio=1.7778;"), a(e, "alt", l = t[12].media[0].name), H(e.src, n = t[0] + "/media/thumb/" + t[12].media[0].url) || a(e, "src", n), a(e, "loading", "lazy"); e = m("img"), a(e, "style", i = "object-position: " + ue(t[13]) + "; aspect-ratio=1.7778;"), a(e, "alt", l = t[13].media[0].name), H(e.src, n = t[0] + "/media/thumb/" + t[13].media[0].url) || a(e, "src", n), a(e, "loading", "lazy");
}, },
m(r, o) { m(r, o) {
p(r, e, o); k(r, e, o);
}, },
p(r, o) { p(r, o) {
o & 32 && i !== (i = "object-position: " + ue(r[12]) + "; aspect-ratio=1.7778;") && a(e, "style", i), o & 32 && l !== (l = r[12].media[0].name) && a(e, "alt", l), o & 33 && !H(e.src, n = r[0] + "/media/thumb/" + r[12].media[0].url) && a(e, "src", n); o & 32 && i !== (i = "object-position: " + ue(r[13]) + "; aspect-ratio=1.7778;") && a(e, "style", i), o & 32 && l !== (l = r[13].media[0].name) && a(e, "alt", l), o & 33 && !H(e.src, n = r[0] + "/media/thumb/" + r[13].media[0].url) && a(e, "src", n);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
function ae(t) { function ae(t) {
let e, i = t[12].place.address + "", l; let e, i = t[13].place.address + "", l;
return { return {
c() { c() {
e = m("span"), l = $(i), a(e, "class", "subtitle"); e = m("span"), l = z(i), a(e, "class", "subtitle");
}, },
m(n, r) { m(n, r) {
p(n, e, r), u(e, l); k(n, e, r), u(e, l);
}, },
p(n, r) { p(n, r) {
r & 32 && i !== (i = n[12].place.address + "") && T(l, i); r & 32 && i !== (i = n[13].place.address + "") && T(l, i);
}, },
d(n) { d(n) {
n && k(e); n && x(e);
} }
}; };
} }
function se(t) { function se(t) {
let e, i = t[12].tags, l = []; let e, i = t[13].tags, l = [];
for (let n = 0; n < i.length; n += 1) for (let n = 0; n < i.length; n += 1)
l[n] = ce(ie(t, i, n)); l[n] = ce(ie(t, i, n));
return { return {
@ -372,13 +372,13 @@ function se(t) {
a(e, "class", "tags"); a(e, "class", "tags");
}, },
m(n, r) { m(n, r) {
p(n, e, r); k(n, e, r);
for (let o = 0; o < l.length; o += 1) for (let o = 0; o < l.length; o += 1)
l[o].m(e, null); l[o].m(e, null);
}, },
p(n, r) { p(n, r) {
if (r & 32) { if (r & 32) {
i = n[12].tags; i = n[13].tags;
let o; let o;
for (o = 0; o < i.length; o += 1) { for (o = 0; o < i.length; o += 1) {
const f = ie(n, i, o); const f = ie(n, i, o);
@ -390,42 +390,41 @@ function se(t) {
} }
}, },
d(n) { d(n) {
n && k(e), be(l, n); n && x(e), be(l, n);
} }
}; };
} }
function ce(t) { function ce(t) {
let e, i, l = t[15] + "", n; let e, i, l = t[16] + "", n;
return { return {
c() { c() {
e = m("span"), i = $("#"), n = $(l), a(e, "class", "tag"); e = m("span"), i = z("#"), n = z(l), a(e, "class", "tag");
}, },
m(r, o) { m(r, o) {
p(r, e, o), u(e, i), u(e, n); k(r, e, o), u(e, i), u(e, n);
}, },
p(r, o) { p(r, o) {
o & 32 && l !== (l = r[15] + "") && T(n, l); o & 32 && l !== (l = r[16] + "") && T(n, l);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
function fe(t) { function fe(t) {
let e, i, l, n, r = V(t[12]) + "", o, f, c, s = t[12].title + "", w, g, _, A, y = t[12].place.name + "", d, z, h, v, C, q, E = t[3] !== "true" && oe(t), j = t[12].place.name !== "online" && ae(t), S = t[12].tags.length && se(t); let e, i, l, n, r = V(t[13]) + "", o, f, s, c = t[13].title + "", w, g, _, A, E = t[13].place.name + "", M, d, h, p, v, q, $ = t[3] !== "true" && oe(t), j = t[13].place.name !== "online" && ae(t), S = t[13].tags.length && se(t);
return { return {
c() { c() {
e = m("a"), E && E.c(), i = M(), l = m("div"), n = m("div"), o = $(r), f = M(), c = m("div"), w = $(s), g = M(), _ = m("span"), A = $('@"'), d = $(y), z = $(`" e = m("a"), $ && $.c(), i = C(), l = m("div"), n = m("div"), o = z(r), f = C(), s = m("div"), w = z(c), g = C(), _ = m("span"), A = z("@"), M = z(E), d = C(), j && j.c(), h = C(), S && S.c(), p = C(), a(n, "class", "subtitle"), a(s, "class", "title"), a(_, "class", "place"), a(l, "class", "content"), a(e, "href", v = t[0] + "/event/" + (t[13].slug || t[13].id)), a(e, "class", "event"), a(e, "title", q = t[13].title), a(e, "target", "_blank");
`), j && j.c(), h = M(), S && S.c(), v = M(), a(n, "class", "subtitle"), a(c, "class", "title"), a(_, "class", "place"), a(l, "class", "content"), a(e, "href", C = t[0] + "/event/" + (t[12].slug || t[12].id)), a(e, "class", "event"), a(e, "title", q = t[12].title), a(e, "target", "_blank");
}, },
m(b, N) { m(b, N) {
p(b, e, N), E && E.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, c), u(c, w), u(l, g), u(l, _), u(_, A), u(_, d), u(_, z), j && j.m(_, null), u(l, h), S && S.m(l, null), u(e, v); k(b, e, N), $ && $.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, s), u(s, w), u(l, g), u(l, _), u(_, A), u(_, M), u(_, d), j && j.m(_, null), u(l, h), S && S.m(l, null), u(e, p);
}, },
p(b, N) { p(b, N) {
b[3] !== "true" ? E ? E.p(b, N) : (E = oe(b), E.c(), E.m(e, i)) : E && (E.d(1), E = null), N & 32 && r !== (r = V(b[12]) + "") && T(o, r), N & 32 && s !== (s = b[12].title + "") && T(w, s), N & 32 && y !== (y = b[12].place.name + "") && T(d, y), b[12].place.name !== "online" ? j ? j.p(b, N) : (j = ae(b), j.c(), j.m(_, null)) : j && (j.d(1), j = null), b[12].tags.length ? S ? S.p(b, N) : (S = se(b), S.c(), S.m(l, null)) : S && (S.d(1), S = null), N & 33 && C !== (C = b[0] + "/event/" + (b[12].slug || b[12].id)) && a(e, "href", C), N & 32 && q !== (q = b[12].title) && a(e, "title", q); b[3] !== "true" ? $ ? $.p(b, N) : ($ = oe(b), $.c(), $.m(e, i)) : $ && ($.d(1), $ = null), N & 32 && r !== (r = V(b[13]) + "") && T(o, r), N & 32 && c !== (c = b[13].title + "") && T(w, c), N & 32 && E !== (E = b[13].place.name + "") && T(M, E), b[13].place.name !== "online" ? j ? j.p(b, N) : (j = ae(b), j.c(), j.m(_, null)) : j && (j.d(1), j = null), b[13].tags.length ? S ? S.p(b, N) : (S = se(b), S.c(), S.m(l, null)) : S && (S.d(1), S = null), N & 33 && v !== (v = b[0] + "/event/" + (b[13].slug || b[13].id)) && a(e, "href", v), N & 32 && q !== (q = b[13].title) && a(e, "title", q);
}, },
d(b) { d(b) {
b && k(e), E && E.d(), j && j.d(), S && S.d(); b && x(e), $ && $.d(), j && j.d(), S && S.d();
} }
}; };
} }
@ -433,10 +432,10 @@ function Ge(t) {
let e, i, l = t[4] && le(t), n = t[5].length && ne(t); let e, i, l = t[4] && le(t), n = t[5].length && ne(t);
return { return {
c() { c() {
l && l.c(), e = M(), n && n.c(), i = pe(), this.c = G; l && l.c(), e = C(), n && n.c(), i = pe(), this.c = G;
}, },
m(r, o) { m(r, o) {
l && l.m(r, o), p(r, e, o), n && n.m(r, o), p(r, i, o); l && l.m(r, o), k(r, e, o), n && n.m(r, o), k(r, i, o);
}, },
p(r, [o]) { p(r, [o]) {
r[4] ? l ? l.p(r, o) : (l = le(r), l.c(), l.m(e.parentNode, e)) : l && (l.d(1), l = null), r[5].length ? n ? n.p(r, o) : (n = ne(r), n.c(), n.m(i.parentNode, i)) : n && (n.d(1), n = null); r[4] ? l ? l.p(r, o) : (l = le(r), l.c(), l.m(e.parentNode, e)) : l && (l.d(1), l = null), r[5].length ? n ? n.p(r, o) : (n = ne(r), n.c(), n.m(i.parentNode, i)) : n && (n.d(1), n = null);
@ -444,7 +443,7 @@ function Ge(t) {
i: G, i: G,
o: G, o: G,
d(r) { d(r) {
l && l.d(r), r && k(e), n && n.d(r), r && k(i); l && l.d(r), r && x(e), n && n.d(r), r && x(i);
} }
}; };
} }
@ -456,34 +455,37 @@ function ue(t) {
return "center center"; return "center center";
} }
function He(t, e, i) { function He(t, e, i) {
let { baseurl: l = "" } = e, { title: n = "" } = e, { maxlength: r = !1 } = e, { tags: o = "" } = e, { places: f = "" } = e, { theme: c = "light" } = e, { show_recurrent: s = !1 } = e, { sidebar: w = "true" } = e, { external_style: g = "" } = e, _ = !1, A = []; let { baseurl: l = "" } = e, { title: n = "" } = e, { maxlength: r = !1 } = e, { collection: o = "" } = e, { tags: f = "" } = e, { places: s = "" } = e, { theme: c = "light" } = e, { show_recurrent: w = !1 } = e, { sidebar: g = "true" } = e, { external_style: _ = "" } = e, A = !1, E = [];
function y(d) { function M(d) {
if (!_) if (!A)
return; return;
const z = []; const h = [];
r && z.push(`max=${r}`), o && z.push(`tags=${o}`), f && z.push(`places=${f}`), z.push(`show_recurrent=${s ? "true" : "false"}`), fetch(`${l}/api/events?${z.join("&")}`).then((h) => h.json()).then((h) => { r && h.push(`max=${r}`);
i(5, A = h); let p = "/api/events";
}).catch((h) => { o ? p = `/api/collections/${o}` : (f && h.push(`tags=${f}`), s && h.push(`places=${s}`)), h.push(`show_recurrent=${w ? "true" : "false"}`), fetch(`${l}${p}?${h.join("&")}`).then((v) => v.json()).then((v) => {
console.error("Error loading Gancio API -> ", h); i(5, E = v.events || v);
}).catch((v) => {
console.error("Error loading Gancio API -> ", v);
}); });
} }
return ke(() => { return ke(() => {
_ = !0, y(); A = !0, M();
}), t.$$set = (d) => { }), t.$$set = (d) => {
"baseurl" in d && i(0, l = d.baseurl), "title" in d && i(1, n = d.title), "maxlength" in d && i(6, r = d.maxlength), "tags" in d && i(7, o = d.tags), "places" in d && i(8, f = d.places), "theme" in d && i(2, c = d.theme), "show_recurrent" in d && i(9, s = d.show_recurrent), "sidebar" in d && i(3, w = d.sidebar), "external_style" in d && i(4, g = d.external_style); "baseurl" in d && i(0, l = d.baseurl), "title" in d && i(1, n = d.title), "maxlength" in d && i(6, r = d.maxlength), "collection" in d && i(7, o = d.collection), "tags" in d && i(8, f = d.tags), "places" in d && i(9, s = d.places), "theme" in d && i(2, c = d.theme), "show_recurrent" in d && i(10, w = d.show_recurrent), "sidebar" in d && i(3, g = d.sidebar), "external_style" in d && i(4, _ = d.external_style);
}, t.$$.update = () => { }, t.$$.update = () => {
t.$$.dirty & 975 && y(); t.$$.dirty & 1999 && M();
}, [ }, [
l, l,
n, n,
c, c,
w,
g, g,
A, _,
E,
r, r,
o, o,
f, f,
s s,
w
]; ];
} }
class Re extends X { class Re extends X {
@ -508,21 +510,23 @@ class Re extends X {
baseurl: 0, baseurl: 0,
title: 1, title: 1,
maxlength: 6, maxlength: 6,
tags: 7, collection: 7,
places: 8, tags: 8,
places: 9,
theme: 2, theme: 2,
show_recurrent: 9, show_recurrent: 10,
sidebar: 3, sidebar: 3,
external_style: 4 external_style: 4
}, },
null null
), e && (e.target && p(e.target, this, e.anchor), e.props && (this.$set(e.props), x())); ), e && (e.target && k(e.target, this, e.anchor), e.props && (this.$set(e.props), y()));
} }
static get observedAttributes() { static get observedAttributes() {
return [ return [
"baseurl", "baseurl",
"title", "title",
"maxlength", "maxlength",
"collection",
"tags", "tags",
"places", "places",
"theme", "theme",
@ -535,72 +539,78 @@ class Re extends X {
return this.$$.ctx[0]; return this.$$.ctx[0];
} }
set baseurl(e) { set baseurl(e) {
this.$$set({ baseurl: e }), x(); this.$$set({ baseurl: e }), y();
} }
get title() { get title() {
return this.$$.ctx[1]; return this.$$.ctx[1];
} }
set title(e) { set title(e) {
this.$$set({ title: e }), x(); this.$$set({ title: e }), y();
} }
get maxlength() { get maxlength() {
return this.$$.ctx[6]; return this.$$.ctx[6];
} }
set maxlength(e) { set maxlength(e) {
this.$$set({ maxlength: e }), x(); this.$$set({ maxlength: e }), y();
} }
get tags() { get collection() {
return this.$$.ctx[7]; return this.$$.ctx[7];
} }
set tags(e) { set collection(e) {
this.$$set({ tags: e }), x(); this.$$set({ collection: e }), y();
} }
get places() { get tags() {
return this.$$.ctx[8]; return this.$$.ctx[8];
} }
set tags(e) {
this.$$set({ tags: e }), y();
}
get places() {
return this.$$.ctx[9];
}
set places(e) { set places(e) {
this.$$set({ places: e }), x(); this.$$set({ places: e }), y();
} }
get theme() { get theme() {
return this.$$.ctx[2]; return this.$$.ctx[2];
} }
set theme(e) { set theme(e) {
this.$$set({ theme: e }), x(); this.$$set({ theme: e }), y();
} }
get show_recurrent() { get show_recurrent() {
return this.$$.ctx[9]; return this.$$.ctx[10];
} }
set show_recurrent(e) { set show_recurrent(e) {
this.$$set({ show_recurrent: e }), x(); this.$$set({ show_recurrent: e }), y();
} }
get sidebar() { get sidebar() {
return this.$$.ctx[3]; return this.$$.ctx[3];
} }
set sidebar(e) { set sidebar(e) {
this.$$set({ sidebar: e }), x(); this.$$set({ sidebar: e }), y();
} }
get external_style() { get external_style() {
return this.$$.ctx[4]; return this.$$.ctx[4];
} }
set external_style(e) { set external_style(e) {
this.$$set({ external_style: e }), x(); this.$$set({ external_style: e }), y();
} }
} }
customElements.define("gancio-events", Re); customElements.define("gancio-events", Re);
function de(t) { function de(t) {
let e, i, l, n, r = t[1].title + "", o, f, c, s = V(t[1]) + "", w, g, _, A, y = t[1].place.name + "", d, z, h = t[1].media.length && he(t); let e, i, l, n, r = t[1].title + "", o, f, s, c = V(t[1]) + "", w, g, _, A, E = t[1].place.name + "", M, d, h = t[1].media.length && he(t);
return { return {
c() { c() {
e = m("a"), h && h.c(), i = M(), l = m("div"), n = m("strong"), o = $(r), f = M(), c = m("div"), w = $(s), g = M(), _ = m("div"), A = $("@"), d = $(y), a(_, "class", "place"), a(l, "class", "container"), a(e, "href", z = t[0] + "/event/" + (t[1].slug || t[1].id)), a(e, "class", "card"), a(e, "target", "_blank"); e = m("a"), h && h.c(), i = C(), l = m("div"), n = m("strong"), o = z(r), f = C(), s = m("div"), w = z(c), g = C(), _ = m("div"), A = z("@"), M = z(E), a(_, "class", "place"), a(l, "class", "container"), a(e, "href", d = t[0] + "/event/" + (t[1].slug || t[1].id)), a(e, "class", "card"), a(e, "target", "_blank");
}, },
m(v, C) { m(p, v) {
p(v, e, C), h && h.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, c), u(c, w), u(l, g), u(l, _), u(_, A), u(_, d); k(p, e, v), h && h.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, s), u(s, w), u(l, g), u(l, _), u(_, A), u(_, M);
}, },
p(v, C) { p(p, v) {
v[1].media.length ? h ? h.p(v, C) : (h = he(v), h.c(), h.m(e, i)) : h && (h.d(1), h = null), C & 2 && r !== (r = v[1].title + "") && T(o, r), C & 2 && s !== (s = V(v[1]) + "") && T(w, s), C & 2 && y !== (y = v[1].place.name + "") && T(d, y), C & 3 && z !== (z = v[0] + "/event/" + (v[1].slug || v[1].id)) && a(e, "href", z); p[1].media.length ? h ? h.p(p, v) : (h = he(p), h.c(), h.m(e, i)) : h && (h.d(1), h = null), v & 2 && r !== (r = p[1].title + "") && T(o, r), v & 2 && c !== (c = V(p[1]) + "") && T(w, c), v & 2 && E !== (E = p[1].place.name + "") && T(M, E), v & 3 && d !== (d = p[0] + "/event/" + (p[1].slug || p[1].id)) && a(e, "href", d);
}, },
d(v) { d(p) {
v && k(e), h && h.d(); p && x(e), h && h.d();
} }
}; };
} }
@ -611,13 +621,13 @@ function he(t) {
e = m("img"), H(e.src, i = t[2](t[1])) || a(e, "src", i), a(e, "alt", l = t[1].media[0].name), a(e, "style", n = "object-position: " + me(t[1]) + "; aspect-ratio=1.7778;"); e = m("img"), H(e.src, i = t[2](t[1])) || a(e, "src", i), a(e, "alt", l = t[1].media[0].name), a(e, "style", n = "object-position: " + me(t[1]) + "; aspect-ratio=1.7778;");
}, },
m(r, o) { m(r, o) {
p(r, e, o); k(r, e, o);
}, },
p(r, o) { p(r, o) {
o & 2 && !H(e.src, i = r[2](r[1])) && a(e, "src", i), o & 2 && l !== (l = r[1].media[0].name) && a(e, "alt", l), o & 2 && n !== (n = "object-position: " + me(r[1]) + "; aspect-ratio=1.7778;") && a(e, "style", n); o & 2 && !H(e.src, i = r[2](r[1])) && a(e, "src", i), o & 2 && l !== (l = r[1].media[0].name) && a(e, "alt", l), o & 2 && n !== (n = "object-position: " + me(r[1]) + "; aspect-ratio=1.7778;") && a(e, "style", n);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
@ -628,7 +638,7 @@ function Ie(t) {
i && i.c(), e = pe(), this.c = G; i && i.c(), e = pe(), this.c = G;
}, },
m(l, n) { m(l, n) {
i && i.m(l, n), p(l, e, n); i && i.m(l, n), k(l, e, n);
}, },
p(l, [n]) { p(l, [n]) {
l[1] ? i ? i.p(l, n) : (i = de(l), i.c(), i.m(e.parentNode, e)) : i && (i.d(1), i = null); l[1] ? i ? i.p(l, n) : (i = de(l), i.c(), i.m(e.parentNode, e)) : i && (i.d(1), i = null);
@ -636,7 +646,7 @@ function Ie(t) {
i: G, i: G,
o: G, o: G,
d(l) { d(l) {
i && i.d(l), l && k(e); i && i.d(l), l && x(e);
} }
}; };
} }
@ -649,20 +659,20 @@ function me(t) {
} }
function Oe(t, e, i) { function Oe(t, e, i) {
let { baseurl: l = "https://demo.gancio.org" } = e, { id: n } = e, r = !1, o; let { baseurl: l = "https://demo.gancio.org" } = e, { id: n } = e, r = !1, o;
function f(s, w) { function f(c, w) {
r && fetch(`${w}/api/event/detail/${s}`).then((g) => g.json()).then((g) => i(1, o = g)); r && fetch(`${w}/api/event/detail/${c}`).then((g) => g.json()).then((g) => i(1, o = g));
} }
ke(() => { ke(() => {
r = !0, f(n, l); r = !0, f(n, l);
}); });
function c(s) { function s(c) {
return `${l}/media/thumb/${s.media[0].url}`; return `${l}/media/thumb/${c.media[0].url}`;
} }
return t.$$set = (s) => { return t.$$set = (c) => {
"baseurl" in s && i(0, l = s.baseurl), "id" in s && i(3, n = s.id); "baseurl" in c && i(0, l = c.baseurl), "id" in c && i(3, n = c.id);
}, t.$$.update = () => { }, t.$$.update = () => {
t.$$.dirty & 9 && f(n, l); t.$$.dirty & 9 && f(n, l);
}, [l, o, c, n]; }, [l, o, s, n];
} }
class Ue extends X { class Ue extends X {
constructor(e) { constructor(e) {
@ -679,7 +689,7 @@ class Ue extends X {
_e, _e,
{ baseurl: 0, id: 3 }, { baseurl: 0, id: 3 },
null null
), e && (e.target && p(e.target, this, e.anchor), e.props && (this.$set(e.props), x())); ), e && (e.target && k(e.target, this, e.anchor), e.props && (this.$set(e.props), y()));
} }
static get observedAttributes() { static get observedAttributes() {
return ["baseurl", "id"]; return ["baseurl", "id"];
@ -688,13 +698,13 @@ class Ue extends X {
return this.$$.ctx[0]; return this.$$.ctx[0];
} }
set baseurl(e) { set baseurl(e) {
this.$$set({ baseurl: e }), x(); this.$$set({ baseurl: e }), y();
} }
get id() { get id() {
return this.$$.ctx[3]; return this.$$.ctx[3];
} }
set id(e) { set id(e) {
this.$$set({ id: e }), x(); this.$$set({ id: e }), y();
} }
} }
customElements.define("gancio-event", Ue); customElements.define("gancio-event", Ue);

View file

@ -1,6 +1,7 @@
html, body { html, body {
scrollbar-width: thin; scrollbar-width: thin;
overflow: auto !important; overflow-y: auto !important;
overflow-x: hidden;
scrollbar-color: #FF4511 #111; scrollbar-color: #FF4511 #111;
font-family: sans-serif; font-family: sans-serif;
} }

View file

@ -47,7 +47,7 @@ v-col(cols=12)
:clear-icon='mdiClose' :clear-icon='mdiClose'
@click:clear='() => change("fromHour")' @click:clear='() => change("fromHour")'
:label="$t('event.from')" :label="$t('event.from')"
:value="value.fromHour" :value="$time.formatHour(value.fromHour)"
:disabled='!value.from' :disabled='!value.from'
readonly readonly
:prepend-icon="mdiClockTimeFourOutline" :prepend-icon="mdiClockTimeFourOutline"
@ -59,7 +59,7 @@ v-col(cols=12)
:value="value.fromHour" :value="value.fromHour"
:allowedMinutes='allowedMinutes' :allowedMinutes='allowedMinutes'
full-width full-width
format='24hr' :format='$time.timeFormat()'
@click:minute='menuFromHour = false' @click:minute='menuFromHour = false'
@input='hr => change("fromHour", hr)') @input='hr => change("fromHour", hr)')
@ -79,7 +79,7 @@ v-col(cols=12)
:clear-icon='mdiClose' :clear-icon='mdiClose'
@click:clear='() => change("dueHour")' @click:clear='() => change("dueHour")'
:label="$t('event.due')" :label="$t('event.due')"
:value="value.dueHour" :value="$time.formatHour(value.dueHour)"
:disabled='!value.fromHour' :disabled='!value.fromHour'
readonly readonly
:prepend-icon="mdiClockTimeEightOutline" :prepend-icon="mdiClockTimeEightOutline"
@ -90,7 +90,7 @@ v-col(cols=12)
:value="value.dueHour" :value="value.dueHour"
full-width full-width
:allowedMinutes='allowedMinutes' :allowedMinutes='allowedMinutes'
format='24hr' :format='$time.timeFormat()'
@click:minute='menuDueHour = false' @click:minute='menuDueHour = false'
@input='hr => change("dueHour", hr)') @input='hr => change("dueHour", hr)')

View file

@ -16,7 +16,7 @@
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn icon large v-bind='attrs' v-on='on' aria-label='Language' v-text="$i18n.locale" /> <v-btn icon large v-bind='attrs' v-on='on' aria-label='Language' v-text="$i18n.locale" />
</template> </template>
<v-list> <v-list dense>
<v-list-item v-for='locale in $i18n.locales' @click.prevent.stop="$i18n.setLocale(locale.code)" :key='locale.code'> <v-list-item v-for='locale in $i18n.locales' @click.prevent.stop="$i18n.setLocale(locale.code)" :key='locale.code'>
<v-list-item-content> <v-list-item-content>
<v-list-item-title v-text='locale.name' /> <v-list-item-title v-text='locale.name' />

View file

@ -1,6 +1,6 @@
<template lang="pug"> <template lang="pug">
v-row v-row
v-col(cols=12) v-col(sm=3 cols=12)
v-switch( v-switch(
v-if='settings.allow_recurrent_event' v-if='settings.allow_recurrent_event'
v-model='show_recurrent' v-model='show_recurrent'
@ -8,12 +8,12 @@ v-row
inset color='primary' inset color='primary'
hide-details hide-details
:label="$t('event.show_recurrent')") :label="$t('event.show_recurrent')")
v-col.mb-4(cols=12) v-col(sm="5" cols=12)
v-autocomplete.p-0( v-autocomplete.p-0(
v-model='meta' :disabled='!!collection'
:label='$t("common.search")' v-model="filters"
:filter='filter' outlined
cache-items :label='$t("common.filter")'
hide-details hide-details
color='primary' color='primary'
hide-selected hide-selected
@ -35,35 +35,65 @@ v-row
@click:close='remove(item)' @click:close='remove(item)'
:close-icon='mdiCloseCircle') :close-icon='mdiCloseCircle')
v-avatar(left) v-avatar(left)
v-icon(small v-text="item.type === 'place' ? mdiMapMarker : mdiTag") v-icon(small v-text="item.type === 'place' ? mdiMapMarker : item.type === 'tag' ? mdiTag : mdiCollage")
span {{ item.label }} span {{ item.label }}
template(v-slot:item='{ item }') template(v-slot:item='{ item }')
v-list-item-avatar v-list-item-avatar
v-icon(v-text="item.type === 'place' ? mdiMapMarker : mdiTag") v-icon(v-text="item.type === 'place' ? mdiMapMarker : item.type === 'tag' ? mdiTag : mdiCollage")
v-list-item-content v-list-item-content
v-list-item-title(v-text='item.label') v-list-item-title(v-text='item.label')
v-list-item-subtitle(v-if='item.type ==="place"' v-text='item.address') v-list-item-subtitle(v-if='item.type ==="place"' v-text='item.label !== "online" && item.address')
v-col(sm=4 cols=12)
v-autocomplete.p-0(
:disabled='!!filters.length'
v-model="collection"
outlined
:label='$t("common.collections")'
hide-details
color='primary'
hide-selected
:menu-props="{ maxWidth: '400' }"
:items='collections'
@change='change'
hide-no-data
clearable
:clear-icon='mdiCloseCircle'
item-text='name')
template(v-slot:itsdfems='{ item }')
v-list-item-avatar
v-icon(v-text="item.type === 'place' ? mdiMapMarker : item.type === 'tag' ? mdiTag : mdiCollage")
v-list-item-content
v-list-item-title(v-text='item.label')
v-list-item-subtitle(v-if='item.type ==="place"' v-text='item.label !== "online" && item.address')
</template> </template>
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import { mdiMapMarker, mdiTag, mdiCloseCircle } from '@mdi/js' import { mdiMapMarker, mdiTag, mdiCloseCircle, mdiCollage } from '@mdi/js'
import debounce from 'lodash/debounce' import debounce from 'lodash/debounce'
export default { export default {
name: 'Search', name: 'Search',
props: { props: {
filters: { type: Object, default: () => ({ }) } value: { type: Object, default: () => ({ }) }
}, },
data () { data () {
return { return {
mdiTag, mdiMapMarker, mdiCloseCircle, mdiTag, mdiMapMarker, mdiCloseCircle, mdiCollage,
meta: [],
items: [], items: [],
show_recurrent: this.filters.show_recurrent || false filters: [],
collection: null,
collections: [],
show_recurrent: this.value.show_recurrent || false
} }
}, },
computed: mapState(['settings']), async fetch () {
this.collections = await this.$axios.$get('/collections')
},
computed: {
...mapState(['settings']),
},
methods: { methods: {
filter (item, queryText, itemText) { filter (item, queryText, itemText) {
return itemText.toLocaleLowerCase().indexOf(queryText.toLocaleLowerCase()) > -1 || return itemText.toLocaleLowerCase().indexOf(queryText.toLocaleLowerCase()) > -1 ||
@ -71,18 +101,31 @@ export default {
}, },
search: debounce(async function(search) { search: debounce(async function(search) {
this.items = await this.$axios.$get(`/event/meta?search=${search.target.value}`) this.items = await this.$axios.$get(`/event/meta?search=${search.target.value}`)
console.error('items ', this.items.length)
}, 100), }, 100),
remove (item) { remove (item) {
this.meta = this.meta.filter(m => m.type !== item.type || m.type === 'place' ? m.id !== item.id : m.label !== item.label) // const filters = {
// tags: this.filters.filter(t => t.type === 'tag' && t.label !== item.label).map(t => t.label),
// places: this.filters.filter(p => p.type === 'place' && p.id !== item.id).map(p => p.id),
// show_recurrent: this.show_recurrent
// }
this.filters = this.filters.filter(m => m.type !== item.type || m.type === 'place' ? m.id !== item.id : m.label !== item.label)
// this.$emit('input', filters)
this.change() this.change()
}, },
change () { change () {
if (this.collection) {
this.filters = []
this.$emit('input', { collection: this.collection, places: [], tags: [], show_recurrent: this.show_recurrent })
} else {
const filters = { const filters = {
tags: this.meta.filter(t => t.type === 'tag').map(t => t.label), tags: this.filters.filter(t => t.type === 'tag').map(t => t.label),
places: this.meta.filter(p => p.type === 'place').map(p => p.id), places: this.filters.filter(p => p.type === 'place').map(p => p.id),
show_recurrent: this.show_recurrent show_recurrent: this.show_recurrent
} }
this.$emit('update', filters) this.$emit('input', filters)
}
} }
} }
} }

View file

@ -79,7 +79,6 @@ v-container
<script> <script>
import { mapActions, mapState } from 'vuex' import { mapActions, mapState } from 'vuex'
import get from 'lodash/get' import get from 'lodash/get'
import axios from 'axios'
import { mdiDeleteForever, mdiPlus, mdiChevronLeft, mdiChevronRight, mdiChevronDown } from '@mdi/js' import { mdiDeleteForever, mdiPlus, mdiChevronLeft, mdiChevronRight, mdiChevronDown } from '@mdi/js'
export default { export default {
@ -140,21 +139,15 @@ export default {
this.instance_url = `https://${this.instance_url}` this.instance_url = `https://${this.instance_url}`
} }
this.instance_url = this.instance_url.replace(/\/$/, '') this.instance_url = this.instance_url.replace(/\/$/, '')
const instance = await this.$axios.$get(`${this.instance_url}/.well-known/nodeinfo/2.1`)
// const instance = await axios.get(`${this.instance_url}/.well-known/nodeinfo/2.1`) this.setSetting({
// // this.setSetting({ key: 'trusted_instances',
// // key: 'trusted_instances', value: this.settings.trusted_instances.concat({
// // value: this.settings.trusted_instances.concat({ url: this.instance_url,
// const instance = { name: get(instance, 'metadata.nodeName', ''),
// url: this.instance_url, label: get(instance, 'metadata.nodeLabel', '')
// name: get(instance, 'data.metadata.nodeName', ''), })
// label: get(instance, 'data.metadata.nodeLabel', ''), })
// actor: get(instance, 'data.medatada.nodeActor', ''),
// timezone: get(instance, 'data.metadata.nodeTimezone', '')
// }
const ret = await this.$axios.$post('/instances/add_friendly', { instance_url: this.instance_url })
console.error(ret)
this.$refs.form.reset() this.$refs.form.reset()
this.dialogAddInstance = false this.dialogAddInstance = false
} catch (e) { } catch (e) {

View file

@ -18,7 +18,7 @@ v-container
:rules="[setting.required ? $validators.required(setting.description) : false]") :rules="[setting.required ? $validators.required(setting.description) : false]")
v-text-field(v-if='setting.type === "NUMBER"' v-model='selectedPlugin.settingsValue[name]' type='number' :label='setting.description') v-text-field(v-if='setting.type === "NUMBER"' v-model='selectedPlugin.settingsValue[name]' type='number' :label='setting.description')
v-switch(v-if='setting.type === "CHECK"' v-model='selectedPlugin.settingsValue[name]' :label='setting.description') v-switch(v-if='setting.type === "CHECK"' v-model='selectedPlugin.settingsValue[name]' :label='setting.description' inset)
v-select(v-if='setting.type === "LIST"' v-model='selectedPlugin.settingsValue[name]' :items='setting.items' :label='setting.description') v-select(v-if='setting.type === "LIST"' v-model='selectedPlugin.settingsValue[name]' :items='setting.items' :label='setting.description')
v-switch(:label="$t('common.enable')" inset color='primary' v-model='selectedPlugin.settingsValue["enable"]') v-switch(:label="$t('common.enable')" inset color='primary' v-model='selectedPlugin.settingsValue["enable"]')
v-card-actions v-card-actions

View file

@ -73,7 +73,7 @@ export default {
computed: mapState(['settings']), computed: mapState(['settings']),
watch: { watch: {
'smtp.secure' (value) { 'smtp.secure' (value) {
this.smtp.port = value ? 465 : 25 this.smtp.port = value ? 465 : 587
} }
}, },
methods: { methods: {

View file

@ -19,6 +19,7 @@ v-container
v-text-field(v-model='new_user.email' v-text-field(v-model='new_user.email'
:label="$t('common.email')" :label="$t('common.email')"
:rules="$validators.email") :rules="$validators.email")
v-text-field(v-model='new_user.description' :label="$t('common.description')")
v-switch(v-model='new_user.is_admin' :label="$t('common.admin')" inset) v-switch(v-model='new_user.is_admin' :label="$t('common.admin')" inset)
v-alert(type='info' :closable='false' :icon='mdiInformation') {{$t('admin.user_add_help')}} v-alert(type='info' :closable='false' :icon='mdiInformation') {{$t('admin.user_add_help')}}
v-card-actions v-card-actions

View file

@ -20,6 +20,13 @@ span
v-list-item-content v-list-item-content
v-list-item-title(v-text="$t('common.edit')") v-list-item-title(v-text="$t('common.edit')")
//- Clone
v-list-item(v-if='!event.parentId' :to='`/add/${event.id}?clone=true`')
v-list-item-icon
v-icon(v-text='mdiScanner')
v-list-item-content
v-list-item-title(v-text="$t('common.clone')")
//- Remove //- Remove
v-list-item(v-if='!event.parentId' @click='remove(false)') v-list-item(v-if='!event.parentId' @click='remove(false)')
v-list-item-icon v-list-item-icon
@ -53,26 +60,13 @@ span
v-list-item-content v-list-item-content
v-list-item-title(v-text="$t('common.remove')") v-list-item-title(v-text="$t('common.remove')")
//- v-btn(text color='primary' v-if='event.is_visible' @click='toggle(false)') {{$t(`common.${event.parentId?'skip':'hide'}`)}}
//- v-btn(text color='success' v-else @click='toggle(false)') <v-icon color='yellow' v-text='mdiAlert'></v-icon> {{$t('common.confirm')}}
//- v-btn(text color='primary' @click='$router.push(`/add/${event.id}`)') {{$t('common.edit')}}
//- v-btn(text color='primary' v-if='!event.parentId' @click='remove(false)') {{$t('common.remove')}}
//- template(v-if='event.parentId')
//- v-divider
//- span.mr-1 <v-icon v-text='mdiRepeat'></v-icon> {{$t('event.edit_recurrent')}}
//- v-btn(text color='primary' v-if='event.parent.is_visible' @click='toggle(true)') {{$t('common.pause')}}
//- v-btn(text color='primary' v-else @click='toggle(true)') {{$t('common.start')}}
//- v-btn(text color='primary' @click='$router.push(`/add/${event.parentId}`)') {{$t('common.edit')}}
//- v-btn(text color='primary' @click='remove(true)') {{$t('common.remove')}}
</template> </template>
<script> <script>
import { mdiChevronUp, mdiRepeat, mdiDelete, mdiCalendarEdit, mdiEyeOff, mdiEye, mdiPause, mdiPlay, mdiDeleteForever } from '@mdi/js' import { mdiChevronUp, mdiRepeat, mdiDelete, mdiCalendarEdit, mdiEyeOff, mdiEye, mdiPause, mdiPlay, mdiDeleteForever, mdiScanner } from '@mdi/js'
export default { export default {
name: 'EventAdmin', name: 'EventAdmin',
data () { data () {
return { mdiChevronUp, mdiRepeat, mdiDelete, mdiCalendarEdit, mdiEyeOff, mdiEye, mdiPause, mdiPlay, mdiDeleteForever } return { mdiChevronUp, mdiRepeat, mdiDelete, mdiCalendarEdit, mdiEyeOff, mdiEye, mdiPause, mdiPlay, mdiDeleteForever, mdiScanner }
}, },
props: { props: {
event: { event: {

View file

@ -25,10 +25,10 @@ function ye(t) {
function u(t, e) { function u(t, e) {
t.appendChild(e); t.appendChild(e);
} }
function p(t, e, i) { function k(t, e, i) {
t.insertBefore(e, i || null); t.insertBefore(e, i || null);
} }
function k(t) { function x(t) {
t.parentNode.removeChild(t); t.parentNode.removeChild(t);
} }
function be(t, e) { function be(t, e) {
@ -38,14 +38,14 @@ function be(t, e) {
function m(t) { function m(t) {
return document.createElement(t); return document.createElement(t);
} }
function $(t) { function z(t) {
return document.createTextNode(t); return document.createTextNode(t);
} }
function M() { function C() {
return $(" "); return z(" ");
} }
function pe() { function pe() {
return $(""); return z("");
} }
function a(t, e, i) { function a(t, e, i) {
i == null ? t.removeAttribute(e) : t.getAttribute(e) !== i && t.setAttribute(e, i); i == null ? t.removeAttribute(e) : t.getAttribute(e) !== i && t.setAttribute(e, i);
@ -69,25 +69,25 @@ let O;
function I(t) { function I(t) {
O = t; O = t;
} }
function $e() { function Ee() {
if (!O) if (!O)
throw new Error("Function called outside component initialization"); throw new Error("Function called outside component initialization");
return O; return O;
} }
function ke(t) { function ke(t) {
$e().$$.on_mount.push(t); Ee().$$.on_mount.push(t);
} }
const R = [], Z = [], P = [], ee = [], Ee = Promise.resolve(); const R = [], Z = [], P = [], ee = [], $e = Promise.resolve();
let K = !1; let K = !1;
function je() { function je() {
K || (K = !0, Ee.then(x)); K || (K = !0, $e.then(y));
} }
function Q(t) { function Q(t) {
P.push(t); P.push(t);
} }
const J = /* @__PURE__ */ new Set(); const J = /* @__PURE__ */ new Set();
let D = 0; let D = 0;
function x() { function y() {
const t = O; const t = O;
do { do {
for (; D < R.length; ) { for (; D < R.length; ) {
@ -120,8 +120,8 @@ function Ce(t, e) {
function Ae(t, e, i, l) { function Ae(t, e, i, l) {
const { fragment: n, on_mount: r, on_destroy: o, after_update: f } = t.$$; const { fragment: n, on_mount: r, on_destroy: o, after_update: f } = t.$$;
n && n.m(e, i), l || Q(() => { n && n.m(e, i), l || Q(() => {
const c = r.map(W).filter(ge); const s = r.map(W).filter(ge);
o ? o.push(...c) : U(c), t.$$.on_mount = []; o ? o.push(...s) : U(s), t.$$.on_mount = [];
}), f.forEach(Q); }), f.forEach(Q);
} }
function Me(t, e) { function Me(t, e) {
@ -132,9 +132,9 @@ function Ne(t, e) {
t.$$.dirty[0] === -1 && (R.push(t), je(), t.$$.dirty.fill(0)), t.$$.dirty[e / 31 | 0] |= 1 << e % 31; t.$$.dirty[0] === -1 && (R.push(t), je(), t.$$.dirty.fill(0)), t.$$.dirty[e / 31 | 0] |= 1 << e % 31;
} }
function we(t, e, i, l, n, r, o, f = [-1]) { function we(t, e, i, l, n, r, o, f = [-1]) {
const c = O; const s = O;
I(t); I(t);
const s = t.$$ = { const c = t.$$ = {
fragment: null, fragment: null,
ctx: null, ctx: null,
props: r, props: r,
@ -146,26 +146,26 @@ function we(t, e, i, l, n, r, o, f = [-1]) {
on_disconnect: [], on_disconnect: [],
before_update: [], before_update: [],
after_update: [], after_update: [],
context: new Map(e.context || (c ? c.$$.context : [])), context: new Map(e.context || (s ? s.$$.context : [])),
callbacks: Y(), callbacks: Y(),
dirty: f, dirty: f,
skip_bound: !1, skip_bound: !1,
root: e.target || c.$$.root root: e.target || s.$$.root
}; };
o && o(s.root); o && o(c.root);
let w = !1; let w = !1;
if (s.ctx = i ? i(t, e.props || {}, (g, _, ...A) => { if (c.ctx = i ? i(t, e.props || {}, (g, _, ...A) => {
const y = A.length ? A[0] : _; const E = A.length ? A[0] : _;
return s.ctx && n(s.ctx[g], s.ctx[g] = y) && (!s.skip_bound && s.bound[g] && s.bound[g](y), w && Ne(t, g)), _; return c.ctx && n(c.ctx[g], c.ctx[g] = E) && (!c.skip_bound && c.bound[g] && c.bound[g](E), w && Ne(t, g)), _;
}) : [], s.update(), w = !0, U(s.before_update), s.fragment = l ? l(s.ctx) : !1, e.target) { }) : [], c.update(), w = !0, U(c.before_update), c.fragment = l ? l(c.ctx) : !1, e.target) {
if (e.hydrate) { if (e.hydrate) {
const g = xe(e.target); const g = xe(e.target);
s.fragment && s.fragment.l(g), g.forEach(k); c.fragment && c.fragment.l(g), g.forEach(x);
} else } else
s.fragment && s.fragment.c(); c.fragment && c.fragment.c();
e.intro && Ce(t.$$.fragment), Ae(t, e.target, e.anchor, e.customElement), x(); e.intro && Ce(t.$$.fragment), Ae(t, e.target, e.anchor, e.customElement), y();
} }
I(c); I(s);
} }
let X; let X;
typeof HTMLElement == "function" && (X = class extends HTMLElement { typeof HTMLElement == "function" && (X = class extends HTMLElement {
@ -213,11 +213,11 @@ function V(t) {
} }
function te(t, e, i) { function te(t, e, i) {
const l = t.slice(); const l = t.slice();
return l[12] = e[i], l; return l[13] = e[i], l;
} }
function ie(t, e, i) { function ie(t, e, i) {
const l = t.slice(); const l = t.slice();
return l[15] = e[i], l; return l[16] = e[i], l;
} }
function le(t) { function le(t) {
let e; let e;
@ -226,13 +226,13 @@ function le(t) {
e = m("link"), a(e, "rel", "stylesheet"), a(e, "href", t[4]); e = m("link"), a(e, "rel", "stylesheet"), a(e, "href", t[4]);
}, },
m(i, l) { m(i, l) {
p(i, e, l); k(i, e, l);
}, },
p(i, l) { p(i, l) {
l & 16 && a(e, "href", i[4]); l & 16 && a(e, "href", i[4]);
}, },
d(i) { d(i) {
i && k(e); i && x(e);
} }
}; };
} }
@ -242,32 +242,32 @@ function ne(t) {
r[o] = fe(te(t, n, o)); r[o] = fe(te(t, n, o));
return { return {
c() { c() {
e = m("div"), l && l.c(), i = M(); e = m("div"), l && l.c(), i = C();
for (let o = 0; o < r.length; o += 1) for (let o = 0; o < r.length; o += 1)
r[o].c(); r[o].c();
a(e, "id", "gancioEvents"), L(e, "dark", t[2] === "dark"), L(e, "light", t[2] === "light"), L(e, "sidebar", t[3] === "true"), L(e, "nosidebar", t[3] !== "true"); a(e, "id", "gancioEvents"), L(e, "dark", t[2] === "dark"), L(e, "light", t[2] === "light"), L(e, "sidebar", t[3] === "true"), L(e, "nosidebar", t[3] !== "true");
}, },
m(o, f) { m(o, f) {
p(o, e, f), l && l.m(e, null), u(e, i); k(o, e, f), l && l.m(e, null), u(e, i);
for (let c = 0; c < r.length; c += 1) for (let s = 0; s < r.length; s += 1)
r[c].m(e, null); r[s].m(e, null);
}, },
p(o, f) { p(o, f) {
if (o[1] && o[3] === "true" ? l ? l.p(o, f) : (l = re(o), l.c(), l.m(e, i)) : l && (l.d(1), l = null), f & 41) { if (o[1] && o[3] === "true" ? l ? l.p(o, f) : (l = re(o), l.c(), l.m(e, i)) : l && (l.d(1), l = null), f & 41) {
n = o[5]; n = o[5];
let c; let s;
for (c = 0; c < n.length; c += 1) { for (s = 0; s < n.length; s += 1) {
const s = te(o, n, c); const c = te(o, n, s);
r[c] ? r[c].p(s, f) : (r[c] = fe(s), r[c].c(), r[c].m(e, null)); r[s] ? r[s].p(c, f) : (r[s] = fe(c), r[s].c(), r[s].m(e, null));
} }
for (; c < r.length; c += 1) for (; s < r.length; s += 1)
r[c].d(1); r[s].d(1);
r.length = n.length; r.length = n.length;
} }
f & 4 && L(e, "dark", o[2] === "dark"), f & 4 && L(e, "light", o[2] === "light"), f & 8 && L(e, "sidebar", o[3] === "true"), f & 8 && L(e, "nosidebar", o[3] !== "true"); f & 4 && L(e, "dark", o[2] === "dark"), f & 4 && L(e, "light", o[2] === "light"), f & 8 && L(e, "sidebar", o[3] === "true"), f & 8 && L(e, "nosidebar", o[3] !== "true");
}, },
d(o) { d(o) {
o && k(e), l && l.d(), be(r, o); o && x(e), l && l.d(), be(r, o);
} }
}; };
} }
@ -275,23 +275,23 @@ function re(t) {
let e, i, l, n, r, o, f; let e, i, l, n, r, o, f;
return { return {
c() { c() {
e = m("a"), i = m("div"), l = m("div"), n = $(t[1]), r = M(), o = m("img"), a(l, "class", "title"), a(o, "id", "logo"), a(o, "alt", "logo"), H(o.src, f = t[0] + "/logo.png") || a(o, "src", f), a(i, "class", "content"), a(e, "href", t[0]), a(e, "target", "_blank"), a(e, "id", "header"); e = m("a"), i = m("div"), l = m("div"), n = z(t[1]), r = C(), o = m("img"), a(l, "class", "title"), a(o, "id", "logo"), a(o, "alt", "logo"), H(o.src, f = t[0] + "/logo.png") || a(o, "src", f), a(i, "class", "content"), a(e, "href", t[0]), a(e, "target", "_blank"), a(e, "id", "header");
}, },
m(c, s) { m(s, c) {
p(c, e, s), u(e, i), u(i, l), u(l, n), u(i, r), u(i, o); k(s, e, c), u(e, i), u(i, l), u(l, n), u(i, r), u(i, o);
}, },
p(c, s) { p(s, c) {
s & 2 && T(n, c[1]), s & 1 && !H(o.src, f = c[0] + "/logo.png") && a(o, "src", f), s & 1 && a(e, "href", c[0]); c & 2 && T(n, s[1]), c & 1 && !H(o.src, f = s[0] + "/logo.png") && a(o, "src", f), c & 1 && a(e, "href", s[0]);
}, },
d(c) { d(s) {
c && k(e); s && x(e);
} }
}; };
} }
function oe(t) { function oe(t) {
let e; let e;
function i(r, o) { function i(r, o) {
return r[12].media.length ? Le : Te; return r[13].media.length ? Le : Te;
} }
let l = i(t), n = l(t); let l = i(t), n = l(t);
return { return {
@ -299,13 +299,13 @@ function oe(t) {
e = m("div"), n.c(), a(e, "class", "img"); e = m("div"), n.c(), a(e, "class", "img");
}, },
m(r, o) { m(r, o) {
p(r, e, o), n.m(e, null); k(r, e, o), n.m(e, null);
}, },
p(r, o) { p(r, o) {
l === (l = i(r)) && n ? n.p(r, o) : (n.d(1), n = l(r), n && (n.c(), n.m(e, null))); l === (l = i(r)) && n ? n.p(r, o) : (n.d(1), n = l(r), n && (n.c(), n.m(e, null)));
}, },
d(r) { d(r) {
r && k(e), n.d(); r && x(e), n.d();
} }
}; };
} }
@ -313,16 +313,16 @@ function Te(t) {
let e, i, l; let e, i, l;
return { return {
c() { c() {
e = m("img"), a(e, "style", "aspect-ratio=1.7778;"), a(e, "alt", i = t[12].title), H(e.src, l = t[0] + "/fallbackimage.png") || a(e, "src", l), a(e, "loading", "lazy"); e = m("img"), a(e, "style", "aspect-ratio=1.7778;"), a(e, "alt", i = t[13].title), H(e.src, l = t[0] + "/fallbackimage.png") || a(e, "src", l), a(e, "loading", "lazy");
}, },
m(n, r) { m(n, r) {
p(n, e, r); k(n, e, r);
}, },
p(n, r) { p(n, r) {
r & 32 && i !== (i = n[12].title) && a(e, "alt", i), r & 1 && !H(e.src, l = n[0] + "/fallbackimage.png") && a(e, "src", l); r & 32 && i !== (i = n[13].title) && a(e, "alt", i), r & 1 && !H(e.src, l = n[0] + "/fallbackimage.png") && a(e, "src", l);
}, },
d(n) { d(n) {
n && k(e); n && x(e);
} }
}; };
} }
@ -330,38 +330,38 @@ function Le(t) {
let e, i, l, n; let e, i, l, n;
return { return {
c() { c() {
e = m("img"), a(e, "style", i = "object-position: " + ue(t[12]) + "; aspect-ratio=1.7778;"), a(e, "alt", l = t[12].media[0].name), H(e.src, n = t[0] + "/media/thumb/" + t[12].media[0].url) || a(e, "src", n), a(e, "loading", "lazy"); e = m("img"), a(e, "style", i = "object-position: " + ue(t[13]) + "; aspect-ratio=1.7778;"), a(e, "alt", l = t[13].media[0].name), H(e.src, n = t[0] + "/media/thumb/" + t[13].media[0].url) || a(e, "src", n), a(e, "loading", "lazy");
}, },
m(r, o) { m(r, o) {
p(r, e, o); k(r, e, o);
}, },
p(r, o) { p(r, o) {
o & 32 && i !== (i = "object-position: " + ue(r[12]) + "; aspect-ratio=1.7778;") && a(e, "style", i), o & 32 && l !== (l = r[12].media[0].name) && a(e, "alt", l), o & 33 && !H(e.src, n = r[0] + "/media/thumb/" + r[12].media[0].url) && a(e, "src", n); o & 32 && i !== (i = "object-position: " + ue(r[13]) + "; aspect-ratio=1.7778;") && a(e, "style", i), o & 32 && l !== (l = r[13].media[0].name) && a(e, "alt", l), o & 33 && !H(e.src, n = r[0] + "/media/thumb/" + r[13].media[0].url) && a(e, "src", n);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
function ae(t) { function ae(t) {
let e, i = t[12].place.address + "", l; let e, i = t[13].place.address + "", l;
return { return {
c() { c() {
e = m("span"), l = $(i), a(e, "class", "subtitle"); e = m("span"), l = z(i), a(e, "class", "subtitle");
}, },
m(n, r) { m(n, r) {
p(n, e, r), u(e, l); k(n, e, r), u(e, l);
}, },
p(n, r) { p(n, r) {
r & 32 && i !== (i = n[12].place.address + "") && T(l, i); r & 32 && i !== (i = n[13].place.address + "") && T(l, i);
}, },
d(n) { d(n) {
n && k(e); n && x(e);
} }
}; };
} }
function se(t) { function se(t) {
let e, i = t[12].tags, l = []; let e, i = t[13].tags, l = [];
for (let n = 0; n < i.length; n += 1) for (let n = 0; n < i.length; n += 1)
l[n] = ce(ie(t, i, n)); l[n] = ce(ie(t, i, n));
return { return {
@ -372,13 +372,13 @@ function se(t) {
a(e, "class", "tags"); a(e, "class", "tags");
}, },
m(n, r) { m(n, r) {
p(n, e, r); k(n, e, r);
for (let o = 0; o < l.length; o += 1) for (let o = 0; o < l.length; o += 1)
l[o].m(e, null); l[o].m(e, null);
}, },
p(n, r) { p(n, r) {
if (r & 32) { if (r & 32) {
i = n[12].tags; i = n[13].tags;
let o; let o;
for (o = 0; o < i.length; o += 1) { for (o = 0; o < i.length; o += 1) {
const f = ie(n, i, o); const f = ie(n, i, o);
@ -390,42 +390,41 @@ function se(t) {
} }
}, },
d(n) { d(n) {
n && k(e), be(l, n); n && x(e), be(l, n);
} }
}; };
} }
function ce(t) { function ce(t) {
let e, i, l = t[15] + "", n; let e, i, l = t[16] + "", n;
return { return {
c() { c() {
e = m("span"), i = $("#"), n = $(l), a(e, "class", "tag"); e = m("span"), i = z("#"), n = z(l), a(e, "class", "tag");
}, },
m(r, o) { m(r, o) {
p(r, e, o), u(e, i), u(e, n); k(r, e, o), u(e, i), u(e, n);
}, },
p(r, o) { p(r, o) {
o & 32 && l !== (l = r[15] + "") && T(n, l); o & 32 && l !== (l = r[16] + "") && T(n, l);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
function fe(t) { function fe(t) {
let e, i, l, n, r = V(t[12]) + "", o, f, c, s = t[12].title + "", w, g, _, A, y = t[12].place.name + "", d, z, h, v, C, q, E = t[3] !== "true" && oe(t), j = t[12].place.name !== "online" && ae(t), S = t[12].tags.length && se(t); let e, i, l, n, r = V(t[13]) + "", o, f, s, c = t[13].title + "", w, g, _, A, E = t[13].place.name + "", M, d, h, p, v, q, $ = t[3] !== "true" && oe(t), j = t[13].place.name !== "online" && ae(t), S = t[13].tags.length && se(t);
return { return {
c() { c() {
e = m("a"), E && E.c(), i = M(), l = m("div"), n = m("div"), o = $(r), f = M(), c = m("div"), w = $(s), g = M(), _ = m("span"), A = $('@"'), d = $(y), z = $(`" e = m("a"), $ && $.c(), i = C(), l = m("div"), n = m("div"), o = z(r), f = C(), s = m("div"), w = z(c), g = C(), _ = m("span"), A = z("@"), M = z(E), d = C(), j && j.c(), h = C(), S && S.c(), p = C(), a(n, "class", "subtitle"), a(s, "class", "title"), a(_, "class", "place"), a(l, "class", "content"), a(e, "href", v = t[0] + "/event/" + (t[13].slug || t[13].id)), a(e, "class", "event"), a(e, "title", q = t[13].title), a(e, "target", "_blank");
`), j && j.c(), h = M(), S && S.c(), v = M(), a(n, "class", "subtitle"), a(c, "class", "title"), a(_, "class", "place"), a(l, "class", "content"), a(e, "href", C = t[0] + "/event/" + (t[12].slug || t[12].id)), a(e, "class", "event"), a(e, "title", q = t[12].title), a(e, "target", "_blank");
}, },
m(b, N) { m(b, N) {
p(b, e, N), E && E.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, c), u(c, w), u(l, g), u(l, _), u(_, A), u(_, d), u(_, z), j && j.m(_, null), u(l, h), S && S.m(l, null), u(e, v); k(b, e, N), $ && $.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, s), u(s, w), u(l, g), u(l, _), u(_, A), u(_, M), u(_, d), j && j.m(_, null), u(l, h), S && S.m(l, null), u(e, p);
}, },
p(b, N) { p(b, N) {
b[3] !== "true" ? E ? E.p(b, N) : (E = oe(b), E.c(), E.m(e, i)) : E && (E.d(1), E = null), N & 32 && r !== (r = V(b[12]) + "") && T(o, r), N & 32 && s !== (s = b[12].title + "") && T(w, s), N & 32 && y !== (y = b[12].place.name + "") && T(d, y), b[12].place.name !== "online" ? j ? j.p(b, N) : (j = ae(b), j.c(), j.m(_, null)) : j && (j.d(1), j = null), b[12].tags.length ? S ? S.p(b, N) : (S = se(b), S.c(), S.m(l, null)) : S && (S.d(1), S = null), N & 33 && C !== (C = b[0] + "/event/" + (b[12].slug || b[12].id)) && a(e, "href", C), N & 32 && q !== (q = b[12].title) && a(e, "title", q); b[3] !== "true" ? $ ? $.p(b, N) : ($ = oe(b), $.c(), $.m(e, i)) : $ && ($.d(1), $ = null), N & 32 && r !== (r = V(b[13]) + "") && T(o, r), N & 32 && c !== (c = b[13].title + "") && T(w, c), N & 32 && E !== (E = b[13].place.name + "") && T(M, E), b[13].place.name !== "online" ? j ? j.p(b, N) : (j = ae(b), j.c(), j.m(_, null)) : j && (j.d(1), j = null), b[13].tags.length ? S ? S.p(b, N) : (S = se(b), S.c(), S.m(l, null)) : S && (S.d(1), S = null), N & 33 && v !== (v = b[0] + "/event/" + (b[13].slug || b[13].id)) && a(e, "href", v), N & 32 && q !== (q = b[13].title) && a(e, "title", q);
}, },
d(b) { d(b) {
b && k(e), E && E.d(), j && j.d(), S && S.d(); b && x(e), $ && $.d(), j && j.d(), S && S.d();
} }
}; };
} }
@ -433,10 +432,10 @@ function Ge(t) {
let e, i, l = t[4] && le(t), n = t[5].length && ne(t); let e, i, l = t[4] && le(t), n = t[5].length && ne(t);
return { return {
c() { c() {
l && l.c(), e = M(), n && n.c(), i = pe(), this.c = G; l && l.c(), e = C(), n && n.c(), i = pe(), this.c = G;
}, },
m(r, o) { m(r, o) {
l && l.m(r, o), p(r, e, o), n && n.m(r, o), p(r, i, o); l && l.m(r, o), k(r, e, o), n && n.m(r, o), k(r, i, o);
}, },
p(r, [o]) { p(r, [o]) {
r[4] ? l ? l.p(r, o) : (l = le(r), l.c(), l.m(e.parentNode, e)) : l && (l.d(1), l = null), r[5].length ? n ? n.p(r, o) : (n = ne(r), n.c(), n.m(i.parentNode, i)) : n && (n.d(1), n = null); r[4] ? l ? l.p(r, o) : (l = le(r), l.c(), l.m(e.parentNode, e)) : l && (l.d(1), l = null), r[5].length ? n ? n.p(r, o) : (n = ne(r), n.c(), n.m(i.parentNode, i)) : n && (n.d(1), n = null);
@ -444,7 +443,7 @@ function Ge(t) {
i: G, i: G,
o: G, o: G,
d(r) { d(r) {
l && l.d(r), r && k(e), n && n.d(r), r && k(i); l && l.d(r), r && x(e), n && n.d(r), r && x(i);
} }
}; };
} }
@ -456,34 +455,37 @@ function ue(t) {
return "center center"; return "center center";
} }
function He(t, e, i) { function He(t, e, i) {
let { baseurl: l = "" } = e, { title: n = "" } = e, { maxlength: r = !1 } = e, { tags: o = "" } = e, { places: f = "" } = e, { theme: c = "light" } = e, { show_recurrent: s = !1 } = e, { sidebar: w = "true" } = e, { external_style: g = "" } = e, _ = !1, A = []; let { baseurl: l = "" } = e, { title: n = "" } = e, { maxlength: r = !1 } = e, { collection: o = "" } = e, { tags: f = "" } = e, { places: s = "" } = e, { theme: c = "light" } = e, { show_recurrent: w = !1 } = e, { sidebar: g = "true" } = e, { external_style: _ = "" } = e, A = !1, E = [];
function y(d) { function M(d) {
if (!_) if (!A)
return; return;
const z = []; const h = [];
r && z.push(`max=${r}`), o && z.push(`tags=${o}`), f && z.push(`places=${f}`), z.push(`show_recurrent=${s ? "true" : "false"}`), fetch(`${l}/api/events?${z.join("&")}`).then((h) => h.json()).then((h) => { r && h.push(`max=${r}`);
i(5, A = h); let p = "/api/events";
}).catch((h) => { o ? p = `/api/collections/${o}` : (f && h.push(`tags=${f}`), s && h.push(`places=${s}`)), h.push(`show_recurrent=${w ? "true" : "false"}`), fetch(`${l}${p}?${h.join("&")}`).then((v) => v.json()).then((v) => {
console.error("Error loading Gancio API -> ", h); i(5, E = v.events || v);
}).catch((v) => {
console.error("Error loading Gancio API -> ", v);
}); });
} }
return ke(() => { return ke(() => {
_ = !0, y(); A = !0, M();
}), t.$$set = (d) => { }), t.$$set = (d) => {
"baseurl" in d && i(0, l = d.baseurl), "title" in d && i(1, n = d.title), "maxlength" in d && i(6, r = d.maxlength), "tags" in d && i(7, o = d.tags), "places" in d && i(8, f = d.places), "theme" in d && i(2, c = d.theme), "show_recurrent" in d && i(9, s = d.show_recurrent), "sidebar" in d && i(3, w = d.sidebar), "external_style" in d && i(4, g = d.external_style); "baseurl" in d && i(0, l = d.baseurl), "title" in d && i(1, n = d.title), "maxlength" in d && i(6, r = d.maxlength), "collection" in d && i(7, o = d.collection), "tags" in d && i(8, f = d.tags), "places" in d && i(9, s = d.places), "theme" in d && i(2, c = d.theme), "show_recurrent" in d && i(10, w = d.show_recurrent), "sidebar" in d && i(3, g = d.sidebar), "external_style" in d && i(4, _ = d.external_style);
}, t.$$.update = () => { }, t.$$.update = () => {
t.$$.dirty & 975 && y(); t.$$.dirty & 1999 && M();
}, [ }, [
l, l,
n, n,
c, c,
w,
g, g,
A, _,
E,
r, r,
o, o,
f, f,
s s,
w
]; ];
} }
class Re extends X { class Re extends X {
@ -508,21 +510,23 @@ class Re extends X {
baseurl: 0, baseurl: 0,
title: 1, title: 1,
maxlength: 6, maxlength: 6,
tags: 7, collection: 7,
places: 8, tags: 8,
places: 9,
theme: 2, theme: 2,
show_recurrent: 9, show_recurrent: 10,
sidebar: 3, sidebar: 3,
external_style: 4 external_style: 4
}, },
null null
), e && (e.target && p(e.target, this, e.anchor), e.props && (this.$set(e.props), x())); ), e && (e.target && k(e.target, this, e.anchor), e.props && (this.$set(e.props), y()));
} }
static get observedAttributes() { static get observedAttributes() {
return [ return [
"baseurl", "baseurl",
"title", "title",
"maxlength", "maxlength",
"collection",
"tags", "tags",
"places", "places",
"theme", "theme",
@ -535,72 +539,78 @@ class Re extends X {
return this.$$.ctx[0]; return this.$$.ctx[0];
} }
set baseurl(e) { set baseurl(e) {
this.$$set({ baseurl: e }), x(); this.$$set({ baseurl: e }), y();
} }
get title() { get title() {
return this.$$.ctx[1]; return this.$$.ctx[1];
} }
set title(e) { set title(e) {
this.$$set({ title: e }), x(); this.$$set({ title: e }), y();
} }
get maxlength() { get maxlength() {
return this.$$.ctx[6]; return this.$$.ctx[6];
} }
set maxlength(e) { set maxlength(e) {
this.$$set({ maxlength: e }), x(); this.$$set({ maxlength: e }), y();
} }
get tags() { get collection() {
return this.$$.ctx[7]; return this.$$.ctx[7];
} }
set tags(e) { set collection(e) {
this.$$set({ tags: e }), x(); this.$$set({ collection: e }), y();
} }
get places() { get tags() {
return this.$$.ctx[8]; return this.$$.ctx[8];
} }
set tags(e) {
this.$$set({ tags: e }), y();
}
get places() {
return this.$$.ctx[9];
}
set places(e) { set places(e) {
this.$$set({ places: e }), x(); this.$$set({ places: e }), y();
} }
get theme() { get theme() {
return this.$$.ctx[2]; return this.$$.ctx[2];
} }
set theme(e) { set theme(e) {
this.$$set({ theme: e }), x(); this.$$set({ theme: e }), y();
} }
get show_recurrent() { get show_recurrent() {
return this.$$.ctx[9]; return this.$$.ctx[10];
} }
set show_recurrent(e) { set show_recurrent(e) {
this.$$set({ show_recurrent: e }), x(); this.$$set({ show_recurrent: e }), y();
} }
get sidebar() { get sidebar() {
return this.$$.ctx[3]; return this.$$.ctx[3];
} }
set sidebar(e) { set sidebar(e) {
this.$$set({ sidebar: e }), x(); this.$$set({ sidebar: e }), y();
} }
get external_style() { get external_style() {
return this.$$.ctx[4]; return this.$$.ctx[4];
} }
set external_style(e) { set external_style(e) {
this.$$set({ external_style: e }), x(); this.$$set({ external_style: e }), y();
} }
} }
customElements.define("gancio-events", Re); customElements.define("gancio-events", Re);
function de(t) { function de(t) {
let e, i, l, n, r = t[1].title + "", o, f, c, s = V(t[1]) + "", w, g, _, A, y = t[1].place.name + "", d, z, h = t[1].media.length && he(t); let e, i, l, n, r = t[1].title + "", o, f, s, c = V(t[1]) + "", w, g, _, A, E = t[1].place.name + "", M, d, h = t[1].media.length && he(t);
return { return {
c() { c() {
e = m("a"), h && h.c(), i = M(), l = m("div"), n = m("strong"), o = $(r), f = M(), c = m("div"), w = $(s), g = M(), _ = m("div"), A = $("@"), d = $(y), a(_, "class", "place"), a(l, "class", "container"), a(e, "href", z = t[0] + "/event/" + (t[1].slug || t[1].id)), a(e, "class", "card"), a(e, "target", "_blank"); e = m("a"), h && h.c(), i = C(), l = m("div"), n = m("strong"), o = z(r), f = C(), s = m("div"), w = z(c), g = C(), _ = m("div"), A = z("@"), M = z(E), a(_, "class", "place"), a(l, "class", "container"), a(e, "href", d = t[0] + "/event/" + (t[1].slug || t[1].id)), a(e, "class", "card"), a(e, "target", "_blank");
}, },
m(v, C) { m(p, v) {
p(v, e, C), h && h.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, c), u(c, w), u(l, g), u(l, _), u(_, A), u(_, d); k(p, e, v), h && h.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, s), u(s, w), u(l, g), u(l, _), u(_, A), u(_, M);
}, },
p(v, C) { p(p, v) {
v[1].media.length ? h ? h.p(v, C) : (h = he(v), h.c(), h.m(e, i)) : h && (h.d(1), h = null), C & 2 && r !== (r = v[1].title + "") && T(o, r), C & 2 && s !== (s = V(v[1]) + "") && T(w, s), C & 2 && y !== (y = v[1].place.name + "") && T(d, y), C & 3 && z !== (z = v[0] + "/event/" + (v[1].slug || v[1].id)) && a(e, "href", z); p[1].media.length ? h ? h.p(p, v) : (h = he(p), h.c(), h.m(e, i)) : h && (h.d(1), h = null), v & 2 && r !== (r = p[1].title + "") && T(o, r), v & 2 && c !== (c = V(p[1]) + "") && T(w, c), v & 2 && E !== (E = p[1].place.name + "") && T(M, E), v & 3 && d !== (d = p[0] + "/event/" + (p[1].slug || p[1].id)) && a(e, "href", d);
}, },
d(v) { d(p) {
v && k(e), h && h.d(); p && x(e), h && h.d();
} }
}; };
} }
@ -611,13 +621,13 @@ function he(t) {
e = m("img"), H(e.src, i = t[2](t[1])) || a(e, "src", i), a(e, "alt", l = t[1].media[0].name), a(e, "style", n = "object-position: " + me(t[1]) + "; aspect-ratio=1.7778;"); e = m("img"), H(e.src, i = t[2](t[1])) || a(e, "src", i), a(e, "alt", l = t[1].media[0].name), a(e, "style", n = "object-position: " + me(t[1]) + "; aspect-ratio=1.7778;");
}, },
m(r, o) { m(r, o) {
p(r, e, o); k(r, e, o);
}, },
p(r, o) { p(r, o) {
o & 2 && !H(e.src, i = r[2](r[1])) && a(e, "src", i), o & 2 && l !== (l = r[1].media[0].name) && a(e, "alt", l), o & 2 && n !== (n = "object-position: " + me(r[1]) + "; aspect-ratio=1.7778;") && a(e, "style", n); o & 2 && !H(e.src, i = r[2](r[1])) && a(e, "src", i), o & 2 && l !== (l = r[1].media[0].name) && a(e, "alt", l), o & 2 && n !== (n = "object-position: " + me(r[1]) + "; aspect-ratio=1.7778;") && a(e, "style", n);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
@ -628,7 +638,7 @@ function Ie(t) {
i && i.c(), e = pe(), this.c = G; i && i.c(), e = pe(), this.c = G;
}, },
m(l, n) { m(l, n) {
i && i.m(l, n), p(l, e, n); i && i.m(l, n), k(l, e, n);
}, },
p(l, [n]) { p(l, [n]) {
l[1] ? i ? i.p(l, n) : (i = de(l), i.c(), i.m(e.parentNode, e)) : i && (i.d(1), i = null); l[1] ? i ? i.p(l, n) : (i = de(l), i.c(), i.m(e.parentNode, e)) : i && (i.d(1), i = null);
@ -636,7 +646,7 @@ function Ie(t) {
i: G, i: G,
o: G, o: G,
d(l) { d(l) {
i && i.d(l), l && k(e); i && i.d(l), l && x(e);
} }
}; };
} }
@ -649,20 +659,20 @@ function me(t) {
} }
function Oe(t, e, i) { function Oe(t, e, i) {
let { baseurl: l = "https://demo.gancio.org" } = e, { id: n } = e, r = !1, o; let { baseurl: l = "https://demo.gancio.org" } = e, { id: n } = e, r = !1, o;
function f(s, w) { function f(c, w) {
r && fetch(`${w}/api/event/detail/${s}`).then((g) => g.json()).then((g) => i(1, o = g)); r && fetch(`${w}/api/event/detail/${c}`).then((g) => g.json()).then((g) => i(1, o = g));
} }
ke(() => { ke(() => {
r = !0, f(n, l); r = !0, f(n, l);
}); });
function c(s) { function s(c) {
return `${l}/media/thumb/${s.media[0].url}`; return `${l}/media/thumb/${c.media[0].url}`;
} }
return t.$$set = (s) => { return t.$$set = (c) => {
"baseurl" in s && i(0, l = s.baseurl), "id" in s && i(3, n = s.id); "baseurl" in c && i(0, l = c.baseurl), "id" in c && i(3, n = c.id);
}, t.$$.update = () => { }, t.$$.update = () => {
t.$$.dirty & 9 && f(n, l); t.$$.dirty & 9 && f(n, l);
}, [l, o, c, n]; }, [l, o, s, n];
} }
class Ue extends X { class Ue extends X {
constructor(e) { constructor(e) {
@ -679,7 +689,7 @@ class Ue extends X {
_e, _e,
{ baseurl: 0, id: 3 }, { baseurl: 0, id: 3 },
null null
), e && (e.target && p(e.target, this, e.anchor), e.props && (this.$set(e.props), x())); ), e && (e.target && k(e.target, this, e.anchor), e.props && (this.$set(e.props), y()));
} }
static get observedAttributes() { static get observedAttributes() {
return ["baseurl", "id"]; return ["baseurl", "id"];
@ -688,13 +698,13 @@ class Ue extends X {
return this.$$.ctx[0]; return this.$$.ctx[0];
} }
set baseurl(e) { set baseurl(e) {
this.$$set({ baseurl: e }), x(); this.$$set({ baseurl: e }), y();
} }
get id() { get id() {
return this.$$.ctx[3]; return this.$$.ctx[3];
} }
set id(e) { set id(e) {
this.$$set({ id: e }), x(); this.$$set({ id: e }), y();
} }
} }
customElements.define("gancio-event", Ue); customElements.define("gancio-event", Ue);

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -5,9 +5,59 @@ permalink: /changelog
nav_order: 10 nav_order: 10
--- ---
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
### [1.6.19](https://framagit.org/les/gancio/compare/v1.6.18...v1.6.19) (2023-11-04)
### Bug Fixes
* issue displaying recurrent event string ([a94ccda](https://framagit.org/les/gancio/commit/a94ccda049f7571a9caa90507141a0aac30331a9))
### 1.6.18 - 3 Nov '23
- [feat] allow to specify password while create new user via CLI to [support yunohost](https://github.com/YunoHost-Apps/gancio_ynh/pull/2#discussion_r1364285417)
- [feat] check if I'm reachable to myself to help in [#298](https://framagit.org/les/gancio/-/issues/298)
- [feat] improve recover and user_confirm error messages
- [feat] improve export and allow to export `collections` in rss/ics/widget
- [fix] fix postgres image version in docker-compose [#303](https://framagit.org/les/gancio/-/issues/303)
- [fix] Improve json-ld representation of events [#33](https://framagit.org/les/gancio/-/merge_requests/33)
- [fix] Add description field to admin's new user form, closes [#307](https://framagit.org/les/gancio/-/issues/307)
- [fix] use tls SSLv3 to send email, fix [#192](https://framagit.org/les/gancio/-/issues/192)
- [fix] notify user when accepted, fix [#308](https://framagit.org/les/gancio/-/issues/308)
- [fix] forgot password on active user only
- [fix] make search case insensitive, fix [#301](https://framagit.org/les/gancio/-/issues/301)
### 1.6.17 - 4 Oct '23
- [fix] typo
### 1.6.16 - 4 Oct '23
- [feat] add Czech locale
- [fix] improve datetime validation
### 1.6.15 - 3 Oct '23
- [feat] clone event
- [feat] am/pm / 24hr support, fix [#294](https://framagit.org/les/gancio/-/issues/294) [#264](https://framagit.org/les/gancio/-/issues/264)
- [feat] update telegram plugin bridge to v1.0.3, [#299](https://framagit.org/les/gancio/-/issues/299)
- [feat] include Brazilian Portuguese (pt-br) and Portugual Portuguese (pt-pt) [#292](https://framagit.org/les/gancio/-/issues/292)
- [fix] MariaDB JSON fields manual fix
- [fix] improve some corner case with SMTP From field [#297](https://framagit.org/les/gancio/-/issues/297)
- [fix] CLI has to fail when configuration not present [#284](https://framagit.org/les/gancio/-/issues/284)
- [minor] remove html2text dep from client
- [minor] RSS item's title format is now YYYY-MM-DD, [#300](https://framagit.org/les/gancio/-/issues/300)
### 1.6.14 - 30 June '23
- improve CLI accounts operations ([documentation](https://gancio.org/usage/cli))
- allow plugins to expose API ([documentation](http://gancio.org/dev/plugins))
- allow plugins to access DB ([documentation](http://gancio.org/dev/plugins))
- show map on the places page, [#276]((https://framagit.org/les/gancio/-/issues/276)) #30
- add node v18 support, [#278]((https://framagit.org/les/gancio/-/issues/278))
- fix media update, [#285]((https://framagit.org/les/gancio/-/issues/285))
- fix nodejs v14 compatibility in export
- fix invalid event microdata, [#277]((https://framagit.org/les/gancio/-/issues/277))
- fix recurrent event, [#280]((https://framagit.org/les/gancio/-/issues/280))
- update deps and locales
### 1.6.13 - 16 may '23 ### 1.6.13 - 16 may '23
- fix feed, ics, json exports - fix feed, ics, json exports

View file

@ -52,6 +52,9 @@ POST
| description | `string` | event's description (html accepted and sanitized) | | description | `string` | event's description (html accepted and sanitized) |
| place_name | `string` | the name of the place | | place_name | `string` | the name of the place |
| place_address | `string` | the address of the place | | place_address | `string` | the address of the place |
| place_latitude | `float` | the latitude of the place |
| place_longitude | `float` | the longitude of the place |
| online_locations | `array` | List of online locations |
| start_datetime | `integer` | start timestamp | | start_datetime | `integer` | start timestamp |
| multidate | `integer` | is a multidate event? | | multidate | `integer` | is a multidate event? |
| tags | `array` | List of tags | | tags | `array` | List of tags |

View file

@ -16,16 +16,110 @@ Since **v.1.2.2** you can write your own plugin that react to event related acti
> >
> [**<u>Please share your plugins or your needs</u>**](/contacts) > [**<u>Please share your plugins or your needs</u>**](/contacts)
Plugins should be inside `./plugins` directory, this is an example:
## Example
Here is a complete example of plugins feature: [https://framagit.org/les/gancio/-/blob/master/plugins/gancioPluginExample.js](https://framagit.org/les/gancio/-/blob/master/plugins/gancioPluginExample.js) .
## Basic plugin syntax
A plugin is essentially an `index.js` file inside its own path in `./plugins`, e.g. `./plugins/my-example-plugin/index.js`
```javascript
module.exports = {
}
```
Plugins should be inside `./plugins` directory but you can specify another location using [`plugins_path`](https://gancio.org/install/config#plugins-path) configuration.
## Plugin details
A plugins **MUST** expose a `configuration` key where to specify its details:
```js ```js
const plugin = { module.exports = {
gancio: null, configuration: {
load (gancio) { name: 'Example',
console.error('Plugin GancioPluginExample loaded!') author: 'lesion',
plugin.gancio = gancio url: 'https://framagit.org/les/gancio/plugins/gancioPluginExample.js',
description: 'Example plugin',
settings: {
my_plugin_string_setting: {
type: 'TEXT',
description: 'My plugin string setting',
required: true,
hint: 'My plugin setting support <strong>html too</strong>'
}, },
enable_this_feature_in_my_plugin: {
type: 'CHECK',
description: 'My plugin best feature',
required: true,
hint: 'This feature is super dupe, enable it!'
},
min_post: {
type: 'NUMBER',
description: 'it supports number too'
},
my_default_language: {
description: 'My default language',
type: 'LIST',
items: ['it', 'en', 'fr']
}
}
}
}
```
[![/assets/plugins/settings.png](/assets/plugins/settings.png)](/assets/plugins/settings.png){: data-fancybox="group" data-caption="Home"}
## Load a plugin
When a plugin is enabled by an administrator, Gancio will call the `load` method if specified:
```js
load ({ settings: gancio_settings, db, helpers, log}, settings) {
// access to your plugin local settings
console.info('Your local settings are in ', settings)
console.info(`For example, you can access to your default language setting by using ${settings.my_default_language}`)
// access to gancio settings
console.info(`Gancio settings are in ${gancio_settings}, e.g. ${gancio.settings.baseurl}`)
// log something
log.warn('This is a log entry from my example plugin')
// use the DB (since 1.6.14)
console.info(db.models.findAll())
console.info(db.query('CREATE TABLE IF NOT EXISTS myPluginTable'))
}
```
## Expose an API <span class='label label-yellow'>since 1.6.4</span>
Plugins could have public HTTP endpoints by exposing an express Router in routeAPI object.
```js
const express = require('express')
const routeAPI = express.Router()
routeAPI.get('/test', (req, res) => {
res.json('WOW!')
})
```
This endpoint will be exposed at <your_instance>/api/plugin/<your_plugin_name>/test
## Access to DB <span class='label label-yellow'>since 1.6.4</span>
TODO
## Helpers <span class='label label-red'>DOCUMENTATION NEEDED</span>
- randomString
- sanitizeHTML
- queryParamToBool
## React to events
```js
onEventCreate (event) { onEventCreate (event) {
const eventLink = `${plugin.gancio.settings.baseurl}/event/${event.slug}` const eventLink = `${plugin.gancio.settings.baseurl}/event/${event.slug}`
if (!event.is_visible) { if (!event.is_visible) {
@ -42,10 +136,6 @@ const plugin = {
onEventDelete (event) { onEventDelete (event) {
console.error(`Event "${event.title}" deleted`) console.error(`Event "${event.title}" deleted`)
} }
}
module.exports = plugin
``` ```

View file

@ -2,7 +2,7 @@ version: '3'
services: services:
db: db:
image: postgres image: postgres:15
container_name: postgres container_name: postgres
volumes: volumes:
- ./postgres:/var/lib/postgresql/data - ./postgres:/var/lib/postgresql/data

View file

@ -10,7 +10,7 @@ permalink: /
A shared agenda for local communities. A shared agenda for local communities.
{: .fs-6 } {: .fs-6 }
Last release **[1.6.13 - 16 May 2023](/changelog#1613---16-may-23)** Last release **[1.6.19 - 4 November 2023](/changelog#1619-2023-11-04)**
[Install]({% link install/install.md %}){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } [Install]({% link install/install.md %}){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
[Demo](https://demo.gancio.org){: .btn .btn-green .fs-5 .mb-4 .mb-md-0 .mr-2 } [Demo](https://demo.gancio.org){: .btn .btn-green .fs-5 .mb-4 .mb-md-0 .mr-2 }

View file

@ -53,7 +53,7 @@ put something like this in `/opt/gancio/user_locale/en.json` to override the reg
english: english:
```json ```json
{ {
"registrer": { "register": {
"description": "My new registration page description" "description": "My new registration page description"
} }
} }

View file

@ -55,5 +55,5 @@ You'll need to [setup nginx as a proxy]({% link install/nginx.md %}) then you ca
```bash ```bash
cd /opt/gancio # or where your installation is cd /opt/gancio # or where your installation is
docker-compose pull && docker-compose restart docker-compose pull && docker-compose up -d
``` ```

View file

@ -15,7 +15,7 @@ nav_order: 7
--- ---
## Testing ## Testing
For testing purposes you could skip the nominatim installation and use one of this geocoding providers that run a server for free: For testing purposes you could skip the nominatim installation and use one of these geocoding providers that run a server for free:
- [https://photon.komoot.io/](https://photon.komoot.io/) [Terms of service](https://photon.komoot.io/) - [https://photon.komoot.io/](https://photon.komoot.io/) [Terms of service](https://photon.komoot.io/)
- [https://nominatim.openstreetmap.org/](https://nominatim.openstreetmap.org/) [Terms of service](https://operations.osmfoundation.org/policies/nominatim/) - [https://nominatim.openstreetmap.org/](https://nominatim.openstreetmap.org/) [Terms of service](https://operations.osmfoundation.org/policies/nominatim/)
@ -28,25 +28,25 @@ From [https://nominatim.org/release-docs/latest/admin/Installation/](https://nom
"A minimum of 2GB of RAM is required or installation will fail. For a full planet import 128GB of RAM or more are strongly recommended. Do not report out of memory problems if you have less than 64GB RAM." "A minimum of 2GB of RAM is required or installation will fail. For a full planet import 128GB of RAM or more are strongly recommended. Do not report out of memory problems if you have less than 64GB RAM."
### Planet mirrors ### Planet mirrors
There is a list of planet mirror at [https://wiki.openstreetmap.org/wiki/Planet.osm#Planet.osm_mirrors](https://wiki.openstreetmap.org/wiki/Planet.osm#Planet.osm_mirrors) There is a list of planet mirrors at [https://wiki.openstreetmap.org/wiki/Planet.osm#Planet.osm_mirrors](https://wiki.openstreetmap.org/wiki/Planet.osm#Planet.osm_mirrors)
There you can also find `Country and area extracts`, divided by `Worldwide extract sources` and `Regional extract sources` There you can also find `Country and area extracts`, divided by `Worldwide extract sources` and `Regional extract sources`
### Download an extract ### Download an extract
For Nominatim to work, you will needs to import files in [PBF Format](https://wiki.openstreetmap.org/wiki/PBF_Format) in the PostGis database. Those files have extension `*.osm.pbf`. For Nominatim to work, you need to import files in [PBF Format](https://wiki.openstreetmap.org/wiki/PBF_Format) in the PostGis database. Those files have extension `*.osm.pbf`.
Some of these mirrors provide also incremental updates via [OsmChange](https://wiki.openstreetmap.org/wiki/OsmChange), for example: Some of these mirrors provide also incremental updates via [OsmChange](https://wiki.openstreetmap.org/wiki/OsmChange), for example:
- Provides updates but with a lower detail - These provide updates but with a lower detail
[https://download.geofabrik.de/europe/italy/nord-ovest-updates/nord-ovest-latest.osm.pbf](http://download.geofabrik.de/europe/italy/nord-ovest-latest.osm.pbf) [https://download.geofabrik.de/europe/italy/nord-ovest-updates/nord-ovest-latest.osm.pbf](http://download.geofabrik.de/europe/italy/nord-ovest-latest.osm.pbf)
[https://download.geofabrik.de/europe/italy/nord-ovest-updates/](https://download.geofabrik.de/europe/italy/nord-ovest-updates/) [https://download.geofabrik.de/europe/italy/nord-ovest-updates/](https://download.geofabrik.de/europe/italy/nord-ovest-updates/)
- Does not provide updates but as higher level of detail - This doesn't provide updates but has an higher level of detail
[https://osmit-estratti-test.wmcloud.org/dati/poly/province/pbf/015_Milano_poly.osm.pbf](https://osmit-estratti-test.wmcloud.org/dati/poly/province/pbf/015_Milano_poly.osm.pbf) [https://osmit-estratti-test.wmcloud.org/dati/poly/province/pbf/015_Milano_poly.osm.pbf](https://osmit-estratti-test.wmcloud.org/dati/poly/province/pbf/015_Milano_poly.osm.pbf)
Needs to host multiple areas? Checkout [Osmium](https://osmcode.org/osmium-tool/manual.html), to merge multiple PBF files into one. Do you need to host multiple areas? Checkout [Osmium](https://osmcode.org/osmium-tool/manual.html), to merge multiple PBF files into one.
--- ---
## Install on Debian ## Install on Debian
There is a [detailed documentaion](https://nominatim.org/release-docs/latest/appendix/Install-on-Ubuntu-22/) for installing nominatim on `Ubuntu 22` that should be valid also to install on `Debian`. There is a [detailed documentation](https://nominatim.org/release-docs/latest/appendix/Install-on-Ubuntu-22/) for installing nominatim on `Ubuntu 22` that should be valid also to install on `Debian`.
### Setup ### Setup
[https://nominatim.org/release-docs/latest/appendix/Install-on-Ubuntu-22/#installing-the-required-software](https://nominatim.org/release-docs/latest/appendix/Install-on-Ubuntu-22/#installing-the-required-software) [https://nominatim.org/release-docs/latest/appendix/Install-on-Ubuntu-22/#installing-the-required-software](https://nominatim.org/release-docs/latest/appendix/Install-on-Ubuntu-22/#installing-the-required-software)
@ -54,14 +54,14 @@ There is a [detailed documentaion](https://nominatim.org/release-docs/latest/app
### Building and Configuration ### Building and Configuration
Get the source code from Github and change into the source directory Get the source code from Github and change into the source directory
``` ```bash
cd $USERHOME cd $USERHOME
wget https://nominatim.org/release/Nominatim-4.2.0.tar.bz2 wget https://nominatim.org/release/Nominatim-4.2.0.tar.bz2
tar xf Nominatim-4.2.0.tar.bz2 tar xf Nominatim-4.2.0.tar.bz2
``` ```
The code must be built in a separate directory. Create this directory, then configure and build Nominatim in there: The code must be built in a separate directory. Create this directory, then configure and build Nominatim in there:
``` ```bash
mkdir $USERHOME/build mkdir $USERHOME/build
cd $USERHOME/build cd $USERHOME/build
cmake $USERHOME/Nominatim-4.2.0 cmake $USERHOME/Nominatim-4.2.0
@ -91,13 +91,12 @@ From [https://github.com/mediagis/nominatim-docker](https://github.com/mediagis/
- Clone the project from sources - Clone the project from sources
```bash ```bash
git clone git@github.com:mediagis/nominatim-docker.git git clone git@github.com:mediagis/nominatim-docker.git
# cd nominatim-docker/<version>
cd nominatim-docker/4.2/contrib # released Nov 29, 2022 cd nominatim-docker/4.2/contrib # released Nov 29, 2022
docker-compose pull docker-compose pull
``` ```
- Or, use the template at `docs/docker/nominatim` - Or, use the template at `docs/docker/nominatim`
``` ```bash
cd /opt/gancio/docs/docker/nominatim cd /opt/gancio/docs/docker/nominatim
docker-compose pull docker-compose pull
``` ```
@ -111,15 +110,13 @@ wget https://download.geofabrik.de/europe/italy/nord-ovest-latest.osm.pbf \
``` ```
### Configure the environment file ### Configure the environment file
``` ```bash
cd docs/docker/nominatim/ cd docs/docker/nominatim/
cp .env.example .env cp .env.example .env
``` ```
Create a random password for nominatim a add it to .env file Create a random password for nominatim and add it to .env file
```bash ```bash
NOMINATIM_PASSWORD=random_password; NOMINATIM_PASSWORD=$(echo random_password | openssl passwd --stdin);
NOMINATIM_PASSWORD=$(echo $NOMINATIM_PASSWORD | openssl passwd --stdin);
echo $NOMINATIM_PASSWORD;
sed -i -e 's/\(NOMINATIM_PASSWORD=\)\(.*\)/\1'$NOMINATIM_PASSWORD'/g' .env sed -i -e 's/\(NOMINATIM_PASSWORD=\)\(.*\)/\1'$NOMINATIM_PASSWORD'/g' .env
``` ```

60
docs/usage/cli.md Normal file
View file

@ -0,0 +1,60 @@
---
layout: default
title: CLI
permalink: /usage/cli
nav_order: 2
parent: Usage
has_toc: true
---
# CLI - Command Line Interface
{: .no_toc }
1. TOC
{:toc}
## Using CLI
Gancio is distributed with an embedded CLI.
To use the CLI you need to specify the `config.json` configuration file via `--config <your_config.json>` flag; by default the CLI will look for one in the current directory, so if your current directory is /opt/gancio (having followed the [installation instructions](/install/debian)) there is no need to specify it.
### Using CLI with Docker installation
To use the CLI in a docker installation you can execute a shell inside the container with:
`docker exec --workdir /home/node/data -it gancio sh` and following the normal CLI usage or running commands with:
`docker exec --workdir /home/node/data gancio gancio <your command>`
(the first "gancio" is the container name)
## Users <span class='label label-yellow'>since 1.6.14</span>
All users related sub-commands starts with `gancio users`.
Note that most of this actions could be done from administration panel (Admin > Users).
### List all users
To list all users use
`gancio users list`
### Create a new user
`gancio users create <username|email>` [password]
To create an user with administrator privileges use the `--admin` flag, e.g. `gancio users create admin@example.com --admin`
### Remove a user
`gancio users remove <username|email>`
### Reset password
`gancio users reset-password <username|email>`
### Change administrator privileges
To add administrator privileges to an user:
`gancio users set-admin <username|email>`
To remove administrator privileges from an user:
`gancio users unset-admin <username|email>`

View file

@ -10,13 +10,12 @@ has_toc: true
# Plugins # Plugins
{: .no_toc } {: .no_toc }
This page is a guide to install plugins, if you want to develop one instead look [here](/dev/plugins) This page is a guide to install plugins, if you want to develop one instead look [here](/dev/plugins).
__Please note that some plugins are officially supported and distributed along with the release__
1. TOC 1. TOC
{:toc} {:toc}
## Install ## Install
To install a plugin you have to: To install a plugin you have to:
@ -49,7 +48,7 @@ __with docker__
docker-compose restart docker-compose restart
``` ```
# List of plugins # List of embedded plugins
## __Telegram__ ## __Telegram__
@ -57,6 +56,5 @@ This plugin republishes events to Telegram channels or groups.
The goal is to spread the info of our networks to the capitalist cyberspace, and pull otherwise isolated people to our radical and free part of the internet. The goal is to spread the info of our networks to the capitalist cyberspace, and pull otherwise isolated people to our radical and free part of the internet.
- **Website**: [https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge](https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge) - **Website**: [https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge](https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge)
- **Download**: [gancio-plugin-telegram-bridge-v0.2.0.zip](https://framagit.org/les/gancio-plugin-telegram-bridge/-/archive/v0.2.0/gancio-plugin-telegram-bridge-v0.2.0.zip) - **Release**: https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge/-/commit/af0eed7b42242ba484d9828157f1be0355bba69b
- **Release**: v0.2.0 / 10 Dec '22

@ -1 +1 @@
Subproject commit 971ea23b6a0d4f120387fa47673424c4a6cea21c Subproject commit 6536eb079f31f60597fb20e6f0f0a5eefe02364f

View file

@ -26,7 +26,7 @@
"places": "Llocs", "places": "Llocs",
"settings": "Configuració", "settings": "Configuració",
"actions": "Accions", "actions": "Accions",
"deactivate": "Deshabilita", "deactivate": "Desactiva",
"remove_admin": "Treu els permisos d'admin", "remove_admin": "Treu els permisos d'admin",
"activate": "Activa", "activate": "Activa",
"save": "Desa", "save": "Desa",
@ -106,7 +106,8 @@
"search_coordinates": "Cerca les coordenades", "search_coordinates": "Cerca les coordenades",
"online": "En línia", "online": "En línia",
"test": "Prova", "test": "Prova",
"show_preview": "Previsualitza" "show_preview": "Previsualitza",
"clone": "Clonar"
}, },
"login": { "login": {
"description": "Amb la sessió iniciada pots afegir activitats noves.", "description": "Amb la sessió iniciada pots afegir activitats noves.",

363
locales/cs.json Normal file
View file

@ -0,0 +1,363 @@
{
"admin": {
"announcement_remove_ok": "Oznámení odebráno",
"description_description": "Zobrazuje se v hlavičce stránky vedle názvu",
"config_plugin": "Nastavení doplňků",
"delete_announcement_confirm": "Určitě chceš odebrat toto oznámení?",
"header_image": "Úvodní obrázek",
"instance_locale_description": "Preferovaný jazyk stránek. Někdy je nutné zobrazit zprávy ve stejném jazyce pro všechny (například při zveřejňování událostí skrz ActivityPub nebo v některých e-mailech). V takových případech bude použit vybraný jazyk.",
"delete_footer_link_confirm": "Opravduc chceš odebrat tento odkaz?",
"edit_place": "Upravit místo",
"user_add_help": "Novému uživateli přijde e-mail s potvrzením a odkazem pro vyvoření hesla",
"instance_block_confirm": "Určitě chceš zablokovat instanci {instance}?",
"delete_user_confirm": "Určitě chceš odstranit tohoto uživatele?",
"hide_boost_bookmark_help": "Skryje malé ikony které zobrazují počet boostů a záložek z Fediverse",
"smtp_use_sendmail": "Použít sendmail",
"block_user": "Zablokovat uživatele",
"instance_timezone_description": "Gancio je navrženo aby pracovalo s událostmi z jednoho místa, třeba města. Všechny události v tomto místě budou zobrazování v nastavené časové zóně.",
"geocoding_test_error": "Geokódovací služba není dostupná {service_name}",
"announcement_description": "V této sekci můžeš přidat oznámení které zůstane na domovksé stránce",
"geocoding_provider_type_help": "Defaultní software je Nominatim",
"smtp_test_success": "Testovací email byl odeslán na {admin_email}, prosím zkontroluj svou schránku",
"blocked": "Zablokováno",
"hide_thumbs": "Skrýt náhledy",
"block": "Blokovat",
"domain": "Doména",
"tilelayer_test_button": "Otestovat mapové podklady",
"collections_description": "Sbírky seskupují události podle tagů a míst. Budou se zobrazovat na hlavní stránce",
"edit_tag": "Upravit tag",
"smtp_port": "SMTP Port",
"new_announcement": "Nové oznámení",
"show_resource": "Zobrazit reakci",
"enable_resources": "Povolit reakce",
"title_description": "Používá se v hlavičce stránky, v předmětech e-mailů a v exportech RSS a ICS.",
"allow_recurrent_event": "Povolit pravidelné události",
"add_link": "Přidat odkaz",
"instance_locale": "Defaultní jazyk",
"edit_tag_help": "Můžeš upravit tag tím že ho nahradíš novým nebo existujícím. {n} propojených událostí bude také upraveno.",
"trusted_instances_help": "Seznam spřátelených instancí zobrazených v záhlaví",
"widget": "Widget",
"allow_online_event_hint": "Požadovat URL ",
"known_users": "Známí uživatelé",
"enable_trusted_instances": "Zapnout přátelské instance",
"user_create_ok": "Uživatel vytvořen",
"default_images": "Defaultní obrázky",
"admin_email": "E-mail admina",
"resources": "Reakce",
"smtp_secure": "SMTP zabezpečení (TLS nebo STARTTLS)",
"allow_multidate_event": "Povolit vícedenní události",
"tilelayer_provider": "Poskytovtel mapových podkladů",
"remove_admin": "Odebrat admina",
"instance_place_help": "Zobrazí se na ostatních instancích",
"federation": "Federace / ActivityPub",
"unblock": "Odblokovat",
"footer_links": "Odkazy v patičce",
"instance_name": "Jméno instance",
"delete_trusted_instance_confirm": "Opravdu chceš odebrat tuto položku ze seznamu sprátelených instancí?",
"recurrent_event_visible": "Zobrazit defaultně pravidelné události",
"smtp_description": "<ul><li>Administrátor by měl obdržet e-mail, když je přidána anonymní událost (pokud je to povolené).</li><li>Administrátor by měl obdržet e-mail s žádostí o registraci (pokud jsou povoleny).</li><li>Uživatel by měl obdržet e-mail s žádostí o registraci.</li><li>Uživatel by měl obdržet e-mail s potvrzením registrace.</li><li>Uživatel by měl obdržet potvrzovací e-mail, když ho administrátor přidá přímo.</li><li>Uživatelé by měli obdržet e-mail pro obnovení hesla, když ho zapomněli</li></ul>",
"fallback_image": "Záložní obrázek",
"disable_user_confirm": "Určitě chceš deaktivovat tohoto uživatele?",
"delete_resource_confirm": "Určitě chceš smazat tuto reakci?",
"enable_federation_help": "Bude možné sledovat tuto instanci z Fediverse",
"user_blocked": "Uživatel {user} zablokován",
"smtp_test_button": "Odeslat testovací email",
"event_remove_ok": "Událost odstraněna",
"trusted_instances_label_default": "Spřátelené instance",
"filter_instances": "Filtrovt instance",
"trusted_instances_label": "Štítek zobrazený u spřátelených instancí",
"hide_calendar": "Skrýt kalendář",
"allow_online_event": "Povolit online události",
"allow_geolocation": "Povolit přidávání souřadnic k událostem",
"colors": "Barvy",
"favicon": "Logo",
"geocoding_countrycodes_help": "Umožňuje filtrovat vyhledávání podle PSČ",
"geocoding_provider_help": "Defaultní poskytovatel je Nominatim",
"geocoding_provider": "Poskytovatel geokódování",
"default_images_help": "Musíš <a href='/admin?tab=theme'>obnovit</a> stránku pro zobrazení změn.",
"tilelayer_test_error": "Mapové podklady od {service_name} nejsou dostupné",
"geolocation": "Geolokace",
"event_confirm_description": "Zde můžeš schválit události přidané anonymně",
"tilelayer_test_success": "Mapové podklady od {service_name} jsou funkční",
"geocoding_test_button": "Vyzkoušet geokódování",
"created_at": "Vytvořeno",
"trusted_instances_label_help": "Defaultní štítek je \"Spřátelené instance\"",
"allow_anon_event": "Povolit vytváření anonymních událostí (ty musí být později potvrzeny)?",
"hide_resource": "Skrýt reakci",
"smtp_hostname": "SMTP Hostname",
"select_instance_timezone": "Časové pásmo",
"edit_collection": "Upravit sbírku",
"user_remove_ok": "Uživatel odebrán",
"tilelayer_provider_attribution": "Poděkování",
"user_block_confirm": "Určitě chceš zablokovat uživatele {user}?",
"delete_user": "Odebrat",
"admin_email_help": "Tato adresa bude použitá jako odesílatel e-mailů. Je to také adresa na kterou jsou odesílány zprávy pro admina",
"is_dark": "Tmavý motiv",
"delete_tag_confirm": "Určitě chceš smazat tag \"{tag}\"? Tag bude odstraněn z {0} událostí.",
"allow_registration_description": "Povolit registrace?",
"geolocation_description": "<b>1. Definujte poskytovatele služby geokódování</b>.<br>V současné době jsou z těch uvedených na <a href=\"https://wiki.openstreetmap.org/wiki/Nominatim#Alternatives_.2F_Third-party_providers\">wiki webu OpenStreetMap </a>, podporovány <a href=\"https://github.com/osm-search/Nominatim\">Nominatim</a> a <a href=\"https://github.com/komoot /photon\">Photon</a>.<br>Můžete použít jednu ze souvisejících oficiálních ukázek zkopírováním odkazu v poli 'Geocoding provider':<ul><li>https://nominatim.openstreetmap.org/search (<a href=\"https://operations.osmfoundation.org/policies/nominatim/\">Smluvní podmínky</a>)</li><li>https://photon.komoot.io/api/ (<a href=\"https://photon.komoot.io/\">Smluvní podmínky</a>)</li></ul><br><b>2. Nastavte poskytovatele mapových podkladů.</b><br>Jejich seznam naleznete zde: <a href=\"https://leaflet-extras.github.io/leaflet-providers/preview/\">https: //leaflet-extras.github.io/leaflet-providers/preview/</a>",
"enable_admin_user_confirm": "Určitě chceš dát admin práva {user}?",
"instance_name_help": "Účet pro sledování skrz ActivityPub",
"new_collection": "Nová sbírka",
"geocoding_provider_type": "Software pro geokódování",
"enable_resources_help": "Povolit přidávání reakcí k událostem z Fediverse",
"delete_collection_confirm": "Určitě chceš odstranit sbírku <u>{collection}</u>?",
"add_instance": "Přidat instanci",
"tilelayer_provider_help": "Defaultní posytovatel je OpenStreetMap",
"disable_admin_user_confirm": "Určitě chceš {user} odebrat práva admina?",
"show_smtp_setup": "Nastavení E-mailů",
"geocoding_test_success": "Geokódovací služba {service_name} je funkční",
"hide_boost_bookmark": "Skrýt boosty/záložky",
"filter_users": "Filtrovat uživatele",
"place_description": "Pokud máš adresu místa špatně zadanou, můžeš ji změnit.<br/>Adresa se změní i u všech současných i minulých událostí v tomto místě.",
"instance_place": "Přibližná lokalita této instance",
"add_trusted_instance": "Přidat spřátelenou instanci",
"geocoding_countrycodes": "PSČ",
"delete_resource": "Smazat reakci",
"enable_federation": "Povolit federování",
"wrong_domain_warning": "Adresa v config.json <b>({baseurl})</b> je jiná než ta na kterou se připojuješ <b>({url})</b>"
},
"common": {
"related": "Příbuzné",
"password_updated": "Heslo změněno.",
"follow": "Sledovat",
"hide": "Skrýt",
"embed_help": "Po vložení tohoto kódu do tvého webu bude událost zobrazena takto",
"recover_password": "Obnovit heslo",
"preview": "Náhled",
"media": "Média",
"start": "Spustit",
"email": "E-mail",
"tag": "Štítek",
"events": "Události",
"announcements": "Oznámení",
"edit": "Upravit",
"calendar": "Kalendář",
"plugins": "Doplňky",
"save": "Uložit",
"edit_event": "Upravit událost",
"remove_admin": "Odebrat admina",
"feed": "RSS Zdroj",
"add": "Přidat",
"export": "Export",
"authorize": "Autorizovat",
"feed_url_copied": "Otevři zkopírovaný odkaz ve své RSS čtečce",
"copy_link": "Kopírovat odkaz",
"activate": "Zapnout",
"address": "Adresa",
"user": "Uživatel",
"deactivate": "Vypnout",
"share": "Sdílet",
"add_to_calendar": "Přidat do kalendáře",
"embed": "Vložit na web",
"logout": "Odhlásit se",
"name": "Jméno",
"set_password": "Nastavit heslo",
"new_user": "Nový uživatel",
"moderation": "Moderace",
"latitude": "Latitude",
"ok": "Ok",
"description": "Popis",
"logout_ok": "Odhlášený",
"label": "Označení",
"show_map": "Zobrazit mapu",
"max_events": "N. maximum událostí",
"admin": "Admin",
"info": "Info",
"users": "Uživatelé",
"event": "Událost",
"instances": "Instance",
"admin_actions": "Administrátorské nástroje",
"password": "Heslo",
"me": "Ty",
"enable": "Povolit",
"copied": "Zkopírováno",
"tags": "Štítky",
"delete": "Odstranit",
"cancel": "Zrušit",
"resources": "Zdroje",
"recurring_event_actions": "Akce pravidelných událostí",
"login": "Login",
"about": "About",
"title": "Nadpis",
"search_coordinates": "Vyhledat souřadnice",
"filter": "Filtr",
"federation": "Federace",
"url": "URL",
"follow_me_title": "Sleduj novinky z Fediverse",
"copy": "Kopírovat",
"help_translate": "Pomoc s překladem",
"skip": "Přeskočit",
"places": "Místa",
"pause": "Pozastavit",
"embed_title": "Vložit tuto událost na web",
"collections": "Sbírky",
"displayname": "Zobrazované jméno",
"settings": "Nastavení",
"theme": "Téma",
"actions": "Akce",
"send": "Odeslat",
"import": "Import",
"confirm": "Potvrdit",
"send_via_mail": "Odeslat e-mail",
"home": "Domů",
"reset": "Reset",
"longitude": "Longitude",
"disable": "Zakázat",
"fediverse": "Fediverse",
"add_event": "Přidat událost",
"n_resources": "žádný zdroj|zdroj|{n} zdrojů",
"online": "On-line",
"new_password": "Nové heslo",
"when": "Kdy",
"register": "Registrovat se",
"content": "Obsah",
"activate_user": "Potvrzeno",
"place": "Lokace",
"search": "Vyhledat",
"show_preview": "Zobrazit náhled",
"next": "Další",
"where": "Kde",
"remove": "Odstranit",
"associate": "Propojit",
"what": "Co",
"test": "Test",
"close": "Zavřít"
},
"export": {
"email_description": "Můžeš dostávat události které tě zajímají na e-mail.",
"feed_description": "Chceš-li sledovat nové události z počítače nebo smartphonu bez nutnosti pravidelně chodit na tento web, použij RSS. </p>\n\n<p> S RSS můžeš použávat speciální aplikaci pro příjem novinek z webů, které tě zajímají. Je to dobrý způsob, jak rychle sledovat mnoho stránek, bez nutnosti vytvářet si na nich účet </p>\n\n<li> Pokud máš Android, doporučujeme <a href=\"https://f-droid.org/cs/packages/net.frju.flym/\">Flym</a> nebo Feeder </li>\n<li> Pro iPhone / iPad můžeš použít <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442442?mt=8\"> Feed4U </a> </li> </li>\n<li> Pro stolní / notebook doporučujeme Feedbro, dá se nainstalovat do <a href=\"https://addons.mozilla.org/cs-GB/firefox/addon/feedbroreader/\"> Firefoxu </a> nebo <a href=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnmdfa\"> Chrome </a>. </li>\n<br/>\nPřidej si tento odkaz do své RSS čtečky a zůstaň v obraze.",
"intro": "Na rozdíl od asociálních platforem které dělají vše proto aby si udrželi uživatele a jejich data, my věříme že informace musí být svobodné, stejně jako lidí. Proto můžete získávat aktuality o událostech i bez nutnosti chodit na tuto stránku.",
"list_description": "Pokud máte vlastní webovou stránku a chcete sdílet seznam událostí, použijte tento kód",
"ical_description": "Počítače a telefony jsou obvykle vybaveny aplikací kalendáře která umožňuje připojení vzdáleného kalendáře.",
"insert_your_address": "Vlož svoji e-mailovou adresu"
},
"event": {
"added_anon": "Událost přidána, ještě ale musí být schválena.",
"image_too_big": "Obrázek nesmí být větší než 4MB",
"where_advanced_options": "Místo - Pokročilé možnosti",
"import_description": "Můžete importovat události z jiných platforem pomocí standartních formátů (ics a h-event)",
"online_locations_fallback_urls": "Záložní odkazy",
"address_description": "Jaká je adresa?",
"anon": "Anonym",
"interact_with_me_at": "Interaguj se mnou ve Fediverse na",
"choose_focal_point": "Vyber střed náhledu",
"follow_me_description": "Jeden ze způsobů, jak zůstat v obraze o událostech zveřejněných zde na {title},\nje sledovat účet <u>{account}</u> ve fediverse, například přes Mastodon, a odtamtud případně reagovat na události.<br/><br/>\nPokud jsi nikdy neslyšel*a o Mastodonu a fediverse, doporučujeme přečíst si <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>tento článek</a> .<br/><br/>Níže zadejte svou instanci (např. mastodon.social)",
"import_ICS": "Importovat z ICS",
"interact_with_me": "Sledovat",
"show_recurrent": "pravidelné události",
"confirmed": "Událost potvrzena",
"show_multidate": "vícedenní události",
"normal_description": "Vybrat den.",
"from": "Od",
"updated": "Událost aktualizována",
"show_past": "také předchozí události",
"download_flyer": "Stáhnout leták",
"ics": "ICS",
"not_found": "Událost nenalezena",
"added": "Událost přidána",
"recurrent_2m_days": "Vždy {days} každý druhý měsíc",
"multidate_description": "Jde o festival? Vyber kdy začíná a končí",
"where_advanced_options_description": "Zde můžete nastavit další parametry místa",
"online_locations": "Online místa",
"online_locations_help": "Například adresa videokonferenční místosti, nebo záložní adresa (maximálně 3)",
"edit_recurrent": "Upravit pravidelnou událost:",
"recurrent_2w_days": "Každý druhý: {days}",
"each_2w": "Každý druhý týden",
"media_description": "Můžeš přidat leták (volitelně)",
"due": "do",
"address_geocoded_disclaimer": "Pokud ve výsledcích geokódování nemůžete najít <strong>adresu ulice</strong> nebo <strong>číslo domu</strong>, které hledáte, můžete je ručně vložit do pole 'Adresa', aniž byste ztratili souřadnice. Nezapomeňte také, že projekt <a target=\"_blank\" href=\"https://www.openstreetmap.org/\">OpenStreetMap</a> je otevřen úpravám. Pokud máte Android, doporučujeme aplikaci <a target=\"_blank\" href=\"https://f-droid.org/en/packages/de.westnordost.streetcomplete/\">StreetComplete</a> ",
"alt_text_description": "Popis pro lidi s poruchami zraku",
"recurrent_1m_ordinal": "Každý {n} {days} of the month",
"normal": "Normální",
"recurrent_2m_ordinal": "Každý {n} {days} každý druhý měsíc",
"anon_description": "Můžeš přidat událost bez registrace i přihlášení, budeš ale muset počkat než si ji někdo přečte,\na posoudí její schválení. Pak už nebude možné ji upravova.<br/><br/>\nMůžeš se ale taky <a href='/login'>přihlásit</a> či <a href='/register'>zaregistrovat</a>. Jinak můžeš pokračovat a my se pokusíme odpovědět co nejdřív. ",
"recurrent_1w_days": "Každý {days}",
"recurrent_1m_days": "Vždy {days} v měsící",
"each_week": "Každý týden",
"what_description": "Nadpis",
"only_future": "pouze budoucí události",
"multidate": "Více dní",
"description_description": "Popis",
"recurrent": "Pravidelné",
"remove_recurrent_confirmation": "Přejete si odstranit tuto pravidelnou událost?\nMinulé události budou zachovány, nebudou ale vytvořeny žádné budoucí.",
"where_description": "Kde se událost nachází? Pokud místo ještě neexistuje, můžeš ho vytvořit.",
"address_description_osm": "Vyhledat souřadnice podle adresy (díky <a href='http://osm.org/copyright'>OpenStreetMap</a>)",
"same_day": "ve stejný den",
"recurrent_description": "Vybrat frekvenci a dny",
"import_URL": "Importovat z URL",
"remove_media_confirmation": "Chceš opravdu odstranit obrázek?",
"each_month": "Každý měsíc",
"remove_confirmation": "Určitě chceš odstranit tuto událost?",
"tag_description": "Tag",
"saved": "Událost uložena"
},
"validators": {
"latitude": "Vlož platnou zeměpisnou šířku (-90 < šířka < 90)",
"email": "Vlož platný e-mail",
"longitude": "Vlož platnou zeměpisnou délku (-180 < délka < 180)",
"required": "{fieldName} je nutné vyplnit"
},
"login": {
"insert_email": "Vlož svou e-mailovou adresu",
"not_registered": "Nemáš registraci?",
"description": "Po přihlášení můžeš přidávat nové události.",
"ok": "Přihlášení úspěšné",
"forgot_password": "Zapomenuté heslo?",
"check_email": "Zkontroluj svůj e-mail a spam.",
"error": "Přihlášení se nezdařilo. Zkontroluj údaje."
},
"ordinal": {
"-1": "poslední",
"5": "pátý",
"1": "první",
"2": "druhý",
"3": "třetí",
"4": "čtvrtý"
},
"error": {
"email_taken": "Tento email je již používán.",
"nick_taken": "Tato přezdívka je již používána."
},
"settings": {
"password_updated": "Heslo změněno.",
"remove_account": "Kliknutím na tlačítko bude tvůj účet odstraněn. Vytvořené události budou zachovány.",
"update_confirm": "Chceš uložit změny?",
"danger_section": "Nebezpečná sekce",
"change_password": "Změnit heslo",
"remove_account_confirm": "Tímto permanentně smažeš svůj účet"
},
"confirm": {
"valid": "Tvůj účet je potvrzený, nyní se můžeš <a href=\"/login\">přihlásit</a>",
"title": "Ověření uživatele",
"not_valid": "Něco se pokazilo."
},
"oauth": {
"scopes": {
"event:write": "Přidat a upravovat události"
},
"authorization_request": "Aplikace <code>{app}</code> žádá o následující oprávnění na <code>{instance_name}</code>:",
"redirected_to": "Po potvrzení dojde k přesměrování na <code>{url}</code>"
},
"recover": {
"not_valid_code": "Něco se pokazilo."
},
"setup": {
"start": "Začít",
"completed_description": "<p>Nyní se můžeš přihlásit jako tento uživatel:<br/><br/>Uživatel: <b>{email}</b><br/>Heslo: <b>{password}<b/></p>",
"copy_password_dialog": "Ano, opravdu je pořeba okopírovat si heslo!",
"https_warning": "Přístupuješ na web skrz HTTP, nezapomeň změnit baseurl v config.json pokud budeš nastavovat HTTPS!",
"completed": "Nastavení dokončeno"
},
"register": {
"error": "Chyba: ",
"description": "Sociální hnutí by se měla organizovat a samofinancovat.<br/>\n<br/>Než budeš moci zveřejňovat události, <strong> musí být tvůj účet schválen</strong>, měj na paměti, že <strong>za tímto webem najdeš skutečné lidi</strong>, takže nám prosím napiš dva řádky, abyste věděli, jaké události budeš chtít zveřejňovat.",
"complete": "Registrace byla potvrzena.",
"first_user": "Admin vytvořen"
},
"auth": {
"fail": "Přihlášení se nezdařilo. Máš určitě správné heslo?",
"not_confirmed": "Zatím nepotvrzeno…"
},
"about": "\n <p><a href='https://gancio.org'>Gancio</a> je sdílená nástěnka pro místní komunity.</p>\n "
}

View file

@ -65,7 +65,7 @@
"add_event": "Veranstaltung hinzufügen", "add_event": "Veranstaltung hinzufügen",
"import": "Importieren", "import": "Importieren",
"reset": "Zurücksetzen", "reset": "Zurücksetzen",
"tags": "Markierung", "tags": "Stichworte",
"place": "Ort", "place": "Ort",
"url": "URL", "url": "URL",
"announcements": "Ankündigungen", "announcements": "Ankündigungen",
@ -99,8 +99,14 @@
"plugins": "Plugins", "plugins": "Plugins",
"help_translate": "Hilf beim Übersetzen mit", "help_translate": "Hilf beim Übersetzen mit",
"content": "Inhalt", "content": "Inhalt",
"admin_actions": "Aktionen der Administrierenden", "admin_actions": "Admin-Aktionen",
"recurring_event_actions": "Einstellungen für regelmäßige Veranstaltungen" "recurring_event_actions": "Einstellungen für regelmäßige Veranstaltungen",
"clone": "Klon",
"tag": "Stichwort",
"search_coordinates": "Suche Koordinaten",
"online": "On-line",
"show_preview": "Vorschau anzeigen",
"test": "Test"
}, },
"admin": { "admin": {
"delete_footer_link_confirm": "Möchtest du diesen Link löschen?", "delete_footer_link_confirm": "Möchtest du diesen Link löschen?",
@ -111,7 +117,7 @@
"new_announcement": "Neue Ankündigung", "new_announcement": "Neue Ankündigung",
"edit_place": "Ort bearbeiten", "edit_place": "Ort bearbeiten",
"enable_resources": "Ressourcen freischalten", "enable_resources": "Ressourcen freischalten",
"hide_boost_bookmark_help": "Versteckt die kleinen Icons, die die Anzahl der eingehenden Boosts und Lesezeichen aus dem Fediverse anzeigen", "hide_boost_bookmark_help": "Blendet die kleinen Bilder aus, die die Anzahl der eingehenden Boosts und Lesezeichen aus dem Fediverse anzeigen",
"user_add_help": "Es wird eine E-Mail an die neue nutzende Person mit einem Hinweis auf die Bestätigung der Registrierung und die Wahl eines Passworts gesendet", "user_add_help": "Es wird eine E-Mail an die neue nutzende Person mit einem Hinweis auf die Bestätigung der Registrierung und die Wahl eines Passworts gesendet",
"block_user": "nutzende Person sperren", "block_user": "nutzende Person sperren",
"filter_instances": "Instanzen filtern", "filter_instances": "Instanzen filtern",
@ -132,7 +138,7 @@
"wrong_domain_warning": "Die \"baseurl\" die in config.json konfiguriert ist <b>({baseurl})</b> unterscheidet sich von derjenigen <b>({url})</b> die du besuchst", "wrong_domain_warning": "Die \"baseurl\" die in config.json konfiguriert ist <b>({baseurl})</b> unterscheidet sich von derjenigen <b>({url})</b> die du besuchst",
"instance_place_help": "Diese Textzeile wird im Menü der anderen befreundeten Instanzen angezeigt", "instance_place_help": "Diese Textzeile wird im Menü der anderen befreundeten Instanzen angezeigt",
"place_description": "Falls ein Ort falsch ist oder sich die Adresse ändert, kannst du ihn ändern.<br/>Bitte beachte, dass alle Veranstaltungen, die mit diesem Ort verbunden sind, die Adresse ändern (auch zurückliegende).", "place_description": "Falls ein Ort falsch ist oder sich die Adresse ändert, kannst du ihn ändern.<br/>Bitte beachte, dass alle Veranstaltungen, die mit diesem Ort verbunden sind, die Adresse ändern (auch zurückliegende).",
"enable_admin_user_confirm": "Bist du dir sicher, dass du der nutzenden Person {user} Admin-Rechte gewährst?", "enable_admin_user_confirm": "Bist du dir sicher, dass du {user} Admin-Rechte zuordnen möchtest?",
"trusted_instances_help": "Befreundete Instanzen werden in der Navigationsleiste oben auf der Seite angezeigt", "trusted_instances_help": "Befreundete Instanzen werden in der Navigationsleiste oben auf der Seite angezeigt",
"trusted_instances_label": "Navigationsbezeichnung zu Friend-Instanzen", "trusted_instances_label": "Navigationsbezeichnung zu Friend-Instanzen",
"trusted_instances_label_default": "Freundliche Instanzen", "trusted_instances_label_default": "Freundliche Instanzen",
@ -188,9 +194,9 @@
"config_plugin": "Plugin Konfiguration", "config_plugin": "Plugin Konfiguration",
"hide_thumbs": "Vorschaubilder ausblenden", "hide_thumbs": "Vorschaubilder ausblenden",
"hide_calendar": "Kalender verstecken", "hide_calendar": "Kalender verstecken",
"admin_email_help": "Die Adresse, die wir als Absender für den Versand von E-Mails verwenden. Sie ist auch die Adresse, an die deine E-Mails an die Administrator:innen geschickt werden.", "admin_email_help": "Die Adresse, die wir als Absender für den Versand von E-Mails verwenden. Sie ist auch die Adresse, an die deine Admin-E-Mails geschickt werden",
"blocked": "Geblockt", "blocked": "Geblockt",
"domain": "Domain", "domain": "Internetadresse",
"known_users": "Bekannte Nutzer:innen", "known_users": "Bekannte Nutzer:innen",
"created_at": "Erstellt am", "created_at": "Erstellt am",
"geocoding_provider_type": "Software für Georeferenzierung", "geocoding_provider_type": "Software für Georeferenzierung",
@ -201,18 +207,22 @@
"geocoding_countrycodes_help": "Ermöglicht die Einrichtung eines Filters für die Suche auf der Grundlage von Ländercodes", "geocoding_countrycodes_help": "Ermöglicht die Einrichtung eines Filters für die Suche auf der Grundlage von Ländercodes",
"geocoding_test_button": "Geokodierung testen", "geocoding_test_button": "Geokodierung testen",
"geocoding_test_success": "Der Geokodierdienst unter {service_name} funktioniert", "geocoding_test_success": "Der Geokodierdienst unter {service_name} funktioniert",
"geocoding_test_error": "Der Dienst ist unter der angegebenen Adresse nicht zu erreichen: {service_name}", "geocoding_test_error": "Der Geokodierungs-Dienst ist unter der angegebenen Adresse nicht erreichbar: {service_name}",
"tilelayer_provider": "Kachel-LayerAnbieter", "tilelayer_provider": "Kachel-LayerAnbieter",
"tilelayer_provider_help": "Der Standard-Anbieter ist OpenStreetMap", "tilelayer_provider_help": "Der Standard-Anbieter ist OpenStreetMap",
"tilelayer_provider_attribution": "Namensnennung", "tilelayer_provider_attribution": "Namensnennung",
"tilelayer_test_button": "Kachel-Layer testen", "tilelayer_test_button": "Kachel-Layer testen",
"tilelayer_test_success": "Der Kachel-Layer-Dienst unter {service_name} funktioniert", "tilelayer_test_success": "Der Kachel-Layer-Dienst unter {service_name} funktioniert",
"tilelayer_test_error": "Der Dienst ist unter der angegebenen Adresse nicht zu erreichen: {service_name}", "tilelayer_test_error": "Der Tilelayer-Dienst {service_name} ist nicht erreichbar",
"geolocation": "Geolokation", "geolocation": "Geolokation",
"allow_multidate_event": "Lasse mehrtägige Veranstaltungen zu", "allow_multidate_event": "Lasse mehrtägige Veranstaltungen zu",
"admin_email": "E-Mail von der administrierenden Person", "admin_email": "E-Mail von der administrierenden Person",
"geolocation_description": "<b>1. Bestimme einen Anbieter für einen Geokodierdienst</b>.<br>Derzeit gibt es unter den im <a href=\"https://wiki.openstreetmap.org/wiki/Nominatim#Alternatives_.2F_Third-party_providers\">Wiki von OpenStreetMap</a>, Anbietern Unterstützung für die Software <a href=\"https://github.com/osm-search/Nominatim\">Nominatim</a> und <a href=\"https://github.com/komoot/photon\">Photon</a>.<br>Du kannst eine der entsprechenden offiziellen Demos verwenden, indem du den Link in das Feld \"Geocoding provider\" kopierst:<ul><li>https://nominatim.openstreetmap.org/search (<a href=\"https://operations.osmfoundation.org/policies/nominatim/\">Terms of Service</a>)</li><li>https://photon.komoot.io/api/ (<a href=\"https://photon.komoot.io/\">Terms of Service</a>)</li></ul><br><b>2. Definiere einen Anbieter für Kartenebenen.</b><br>Eine Liste von ihnen findest du hier: <a href=\"https://leaflet-extras.github.io/leaflet-providers/preview/\">https://leaflet-extras.github.io/leaflet-providers/preview/</a>", "geolocation_description": "<b>1. Bestimme einen Anbieter für einen Geokodierdienst</b>.<br>Derzeit gibt es unter den im <a href=\"https://wiki.openstreetmap.org/wiki/Nominatim#Alternatives_.2F_Third-party_providers\">Wiki von OpenStreetMap</a>, Anbietern Unterstützung für die Software <a href=\"https://github.com/osm-search/Nominatim\">Nominatim</a> und <a href=\"https://github.com/komoot/photon\">Photon</a>.<br>Du kannst eine der entsprechenden offiziellen Demos verwenden, indem du den Link in das Feld \"Geocoding provider\" kopierst:<ul><li>https://nominatim.openstreetmap.org/search (<a href=\"https://operations.osmfoundation.org/policies/nominatim/\">Terms of Service</a>)</li><li>https://photon.komoot.io/api/ (<a href=\"https://photon.komoot.io/\">Terms of Service</a>)</li></ul><br><b>2. Definiere einen Anbieter für Kartenebenen.</b><br>Eine Liste von ihnen findest du hier: <a href=\"https://leaflet-extras.github.io/leaflet-providers/preview/\">https://leaflet-extras.github.io/leaflet-providers/preview/</a>",
"default_images_help": "Du musst <a href='/admin?tab=theme'>die Seite neu laden</a>, um die Änderungen sehen zu können." "default_images_help": "Du musst <a href='/admin?tab=theme'>die Seite neu laden</a>, um die Änderungen sehen zu können.",
"edit_tag": "Stichwort bearbeiten",
"allow_online_event_hint": "Nach Internetadressen fragen ",
"allow_online_event": "Erlaube Online-Veranstaltungen",
"colors": "Farben"
}, },
"settings": { "settings": {
"update_confirm": "Willst du deine Änderung speichern?", "update_confirm": "Willst du deine Änderung speichern?",
@ -237,7 +247,9 @@
}, },
"validators": { "validators": {
"required": "{fieldName} ist erforderlich", "required": "{fieldName} ist erforderlich",
"email": "Füge eine gültige E-Mail ein" "email": "Füge eine gültige E-Mail ein",
"latitude": "Gib einen gültigen Breitengrad ein (-90 < Breitengrad < 90)",
"longitude": "Gib einen gültigen Längengrad ein (-180 < Längengrad < 180)"
}, },
"ordinal": { "ordinal": {
"-1": "letzte", "-1": "letzte",
@ -255,7 +267,7 @@
"authorization_request": "Die Anwendung <code>{app}</code> verlangt die Berechtigung die folgenden Aktionen auf <code>{instance_name}</code> ausüben zu können:" "authorization_request": "Die Anwendung <code>{app}</code> verlangt die Berechtigung die folgenden Aktionen auf <code>{instance_name}</code> ausüben zu können:"
}, },
"event": { "event": {
"tag_description": "Markierung", "tag_description": "Stichwort",
"description_description": "Beschreibung", "description_description": "Beschreibung",
"what_description": "Titel", "what_description": "Titel",
"same_day": "am selben Tag", "same_day": "am selben Tag",
@ -274,14 +286,14 @@
"each_2w": "Jede zweite Woche", "each_2w": "Jede zweite Woche",
"ics": "ICS", "ics": "ICS",
"remove_recurrent_confirmation": "Bist du dir sicher, dass du diese wiederkehrende Veranstaltung entfernen möchtest?\nFrühere Veranstaltungen werden beibehalten, aber es werden keine zukünftigen Veranstaltungen mehr hinzugefügt.", "remove_recurrent_confirmation": "Bist du dir sicher, dass du diese wiederkehrende Veranstaltung entfernen möchtest?\nFrühere Veranstaltungen werden beibehalten, aber es werden keine zukünftigen Veranstaltungen mehr hinzugefügt.",
"anon_description": "Du kannst eine Veranstaltung hinzufügen, ohne dich zu registrieren oder anzumelden,\nmusst dann aber warten, bis jemand es liest und bestätigt, dass es eine zulässige Veranstaltung ist.\nEs ist nicht möglich, den Eintrag zu verändern.<br/><br/>\nDu kannst dich stattdessen <a href='/login'>anmelden</a> oder <a href='/register'>registrieren</a>. In diesem Fall solltest du so schnell wie möglich eine Antwort erhalten. ", "anon_description": "Es ist möglich, eine Veranstaltung hinzufügen, ohne vorherige Registrierung oder Anmeldung. Die Veranstaltung wartet, bis sie von einer Person bestätigt wird.\nEs ist nicht möglich, den Eintrag nachträglich zu verändern.<br/><br/>\nDu kannst dich stattdessen <a href='/login'>anmelden</a> oder <a href='/register'>registrieren</a>. Falls nicht, fahre fort. Wir schalten Deine Veranstaltung frei, sobald es uns möglich ist. ",
"where_description": "Wo ist die Veranstaltung? Wenn der Ort noch nicht beschrieben wurde, kannst du ihn selbst eintragen.", "where_description": "Wo ist die Veranstaltung? Wenn der Ort noch nicht beschrieben wurde, kannst du ihn selbst eintragen.",
"coordinates_search": "Suche nach Koordinaten", "coordinates_search": "Suche nach Koordinaten",
"coordinates_search_description": "Sie können den Ort anhand des Namens suchen oder das Koordinatenpaar einfügen.", "coordinates_search_description": "Sie können den Ort anhand des Namens suchen oder das Koordinatenpaar einfügen.",
"follow_me_description": "Eine Möglichkeit, über die hier auf {title} veröffentlichten Veranstaltungen auf dem Laufenden zu bleiben, besteht darin, dem Account <u>{account}</u> aus dem Fediverse zu folgen, zum Beispiel über Mastodon, und von dort aus eventuell Ressourcen für eine Veranstaltung hinzuzufügen.<br/><br/>\nWenn Du noch nie von Mastodon und dem Fediverse gehört hast, empfehlen wir dir, diesen Artikel <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'> zu lesen</a>.<br/><br/>Gib unten deine Instanz ein (z.B. mastodon.social)", "follow_me_description": "Eine Möglichkeit, über die hier auf {title} veröffentlichten Veranstaltungen auf dem Laufenden zu bleiben,\nbesteht darin, dem Account <u>{account}</u> aus dem Fediverse zu folgen, zum Beispiel über Mastodon, und von dort aus eventuell Ressourcen für eine Veranstaltung hinzuzufügen.<br/><br/>\nWenn Du noch nie von Mastodon und dem Fediverse gehört hast, empfehlen wir dir, diesen Artikel <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'> zu lesen</a>.<br/><br/>Gib unten deine Instanz ein (z.B. mastodon.social)",
"media_description": "Du kannst (optional) einen Flyer hinzufügen", "media_description": "Du kannst (optional) einen Flyer hinzufügen",
"edit_recurrent": "Bearbeite eine sich wiederholende Veranstaltung :", "edit_recurrent": "Bearbeite eine sich wiederholende Veranstaltung :",
"show_recurrent": "wiederkehrende Termine", "show_recurrent": "wiederkehrende Veranstaltungen",
"show_past": "auch ältere Veranstaltungen", "show_past": "auch ältere Veranstaltungen",
"only_future": "nur zukünftige Veranstaltungen", "only_future": "nur zukünftige Veranstaltungen",
"recurrent_description": "Wähle die Häufigkeit und Tage aus", "recurrent_description": "Wähle die Häufigkeit und Tage aus",
@ -292,10 +304,10 @@
"recurrent_1w_days": "Jeden {days}", "recurrent_1w_days": "Jeden {days}",
"recurrent_2w_days": "Jeden zweiten {days} eine", "recurrent_2w_days": "Jeden zweiten {days} eine",
"recurrent_1m_days": "Der {days} in jedem Monat", "recurrent_1m_days": "Der {days} in jedem Monat",
"recurrent_2m_days": "Der {days} jeden zweiten Monat", "recurrent_2m_days": "{days}, jeden zweiten Monat",
"recurrent_1m_ordinal": "Jeden {n} {days} im Monat", "recurrent_1m_ordinal": "Alle {n} {days}, im Monat",
"each_week": "Jede Woche", "each_week": "Jede Woche",
"recurrent_2m_ordinal": "Der {n} {days} jeden zweiten Monat", "recurrent_2m_ordinal": "Alle {n} {days}, jeden zweiten Monat",
"each_month": "Jeden Monat", "each_month": "Jeden Monat",
"due": "bis", "due": "bis",
"from": "von", "from": "von",
@ -307,7 +319,13 @@
"alt_text_description": "Beschreibung für Menschen mit Sehbehinderungen", "alt_text_description": "Beschreibung für Menschen mit Sehbehinderungen",
"choose_focal_point": "Auswahl des Schwerpunkts", "choose_focal_point": "Auswahl des Schwerpunkts",
"address_description": "Was ist die Adresse?", "address_description": "Was ist die Adresse?",
"address_description_osm": "Wo ist die Adresse? (<a href='http://osm.org/copyright'>OpenStreetMap</a> contributors)" "address_description_osm": "Koordinaten ermitteln, indem du nach einer Adresse suchst. (<a href='http://osm.org/copyright'>OpenStreetMap</a>-Mitwirkende)",
"where_advanced_options": "Ort Erweiterte Angaben",
"online_locations_fallback_urls": "Alternativadressen",
"show_multidate": "Veranstaltungen mit mehreren Terminen",
"where_advanced_options_description": "Gib hier zusätzliche Angaben zum Ort an",
"online_locations": "Orte online",
"online_locations_help": "Etwa eine Internetadresse eines Videokonferenzraums und eine Alternativadresse (maximal 3)"
}, },
"register": { "register": {
"first_user": "Admin erstellt", "first_user": "Admin erstellt",
@ -320,7 +338,7 @@
"ical_description": "Computer und Smartphones sind üblicherweise mit einer Kalenderanwendung ausgestattet, mit der ein Fernkalender importiert werden kann.", "ical_description": "Computer und Smartphones sind üblicherweise mit einer Kalenderanwendung ausgestattet, mit der ein Fernkalender importiert werden kann.",
"insert_your_address": "Gib deine E-Mail-Adresse ein", "insert_your_address": "Gib deine E-Mail-Adresse ein",
"email_description": "Du kannst interessante Veranstaltungen per E-Mail erhalten.", "email_description": "Du kannst interessante Veranstaltungen per E-Mail erhalten.",
"feed_description": "Um Updates auf deinem Computer oder Smartphone zu erhalten, ohne regelmäßig diese Seite zu öffnen, kannst du RSS-Feeds benutzen. </p>\n\n<p> Mit RSS-Feeds nutzt du eine spezielle App, um Updates von den Seiten, die dich interessieren, zu erhalten. Damit kannst du rasch vielen Seiten folgen, ohne einen\nAccount erstellen zu müssen und ohne sonstige Komplikationen. </p>\n\n<li> Für Android-Geräte empfehlen wir <a href=\"https://f-droid.org/en/packages/net.frju.flym/\">Flym</a> oder Feeder </li>\n<li> Auf iPhones / iPads kannst du <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8\"> Feed4U </a> nutzen</li>\n<li> Auf Desktop-PCs oder Laptops empfehlen wir Feedbro, den du in <a href=\"https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/\"> Firefox </a> oder <a \nref=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa\"> Chrome </a> installieren kannst. </li>\n<br/>\nIndem du diesen Link deinem RSS-Feed-Reader hinzufügst, wirst du auf dem Laufenden gehalten.", "feed_description": "Um Aktualisierungen auf deinem Computer oder Smartphone zu erhalten, ohne regelmäßig diese Seite zu öffnen, kannst du RSS-Feeds benutzen. </p>\n\n<p> Mit RSS-Feeds nutzt du eine spezielle App, um Aktualisierungen von den Seiten, die dich interessieren, zu erhalten. Damit kannst du viele Seiten überblicken, ohne ein Benutzerkonto erstellen zu müssen oder sonstige Komplikationen. </p>\n\n\n<li> Für Android-Geräte empfehlen wir <a href=\"https://f-droid.org/en/packages/net.frju.flym/\">Flym</a> oder Feeder </li>\n<li> Auf iPhones / iPads kannst du <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8\"> Feed4U </a> nutzen</li>\n<li> Auf Desktop-PCs oder Laptops empfehlen wir Feedbro, den du in <a href=\"https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/\"> Firefox </a> oder <a \nref=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa\"> Chrome </a> installieren kannst. </li>\n<br/>\nFügst du diesen Link dem RSS-Feed-Reader hinzu, wird dieser dich auf dem Laufenden halten.",
"intro": "Anders als unsoziale Netzwerke, die alles unternehmen, um nutzende Personen und deren Daten bei sich zu (be)halten, glauben wir, dass Informationen und Menschen gleichermaßen frei sein müssen. Deshalb kannst du dich über Veranstaltungen aktuell informieren, ohne zwangsläufig über diese Seite zu gehen." "intro": "Anders als unsoziale Netzwerke, die alles unternehmen, um nutzende Personen und deren Daten bei sich zu (be)halten, glauben wir, dass Informationen und Menschen gleichermaßen frei sein müssen. Deshalb kannst du dich über Veranstaltungen aktuell informieren, ohne zwangsläufig über diese Seite zu gehen."
}, },
"recover": { "recover": {
@ -329,7 +347,7 @@
"login": { "login": {
"ok": "Angemeldet", "ok": "Angemeldet",
"insert_email": "Gib deine E-Mail-Adresse ein", "insert_email": "Gib deine E-Mail-Adresse ein",
"error": "Anmeldung nicht möglich. Bitte überprüfe deine Informationen zur Anmeldung.", "error": "Anmeldung nicht möglich. Bitte überprüfe die Anmelde-Informationen.",
"forgot_password": "Passwort vergessen?", "forgot_password": "Passwort vergessen?",
"not_registered": "Nicht registriert?", "not_registered": "Nicht registriert?",
"check_email": "Überprüfe deinen E-Mail-Posteingang und Spam.", "check_email": "Überprüfe deinen E-Mail-Posteingang und Spam.",

29
locales/email/cs.json Normal file
View file

@ -0,0 +1,29 @@
{
"register": {
"content": "Přijali jsme žádost o registraci, potvrdíme ji co nejdříve.",
"subject": "Žádost o registraci byla přijata"
},
"user_confirm": {
"content": "Ahoj, tvůj účet na <a href='{{config.baseurl}}'>{{config.title}}</a> byl vytvořený. <a href='{{config.baseurl}}/user_confirm/{{user.recover_code}}'>Potvrď ho a nastav si heslo.</a>.",
"subject": "Nyní můžeš začít zveřejňovat události"
},
"event_confirm": {
"content": "Tuto událost můžeš potvrdit na <a href='{{url}}'>této stránce </a>"
},
"admin_register": {
"subject": "Nová registrace",
"content": "{{user.email}} požádal o registraci na {{config.title}}: <br/><pre>{{user.description}}</pre><br/> Potvrď ji <a href='{{config.baseurl}}/admin'>zde</a>."
},
"confirm": {
"subject": "Teď můžete začít zveřejňovat události",
"content": "Ahoj, tvůj účet na <a href='{{config.baseurl}}'>{{config.title}}</a> byl schválený. Napiš nám na {{config.admin_email}} pokud potřebuješ další informace."
},
"recover": {
"subject": "Obnova hesla",
"content": "Ahoj, požádali jste o změnu hesla na {{config.title}}. <a href='{{config.baseurl}}/recover/{{user.recover_code}}'>Klikni zde</a> pro potvrzení."
},
"test": {
"content": "Toto je testovací email, nastavení je funkční.",
"subject": "Nastavení SMTP je funkční"
}
}

View file

@ -24,6 +24,6 @@
}, },
"test": { "test": {
"content": "Dieses ist eine Test-E-Mail. Wenn du das hier lesen kannst, dann funktioniert deine Konfiguration richtig.", "content": "Dieses ist eine Test-E-Mail. Wenn du das hier lesen kannst, dann funktioniert deine Konfiguration richtig.",
"subject": "Deine SMTP Konfiguration funktioniert" "subject": "Deine SMTP-Konfiguration funktioniert"
} }
} }

29
locales/email/pt-BR.json Normal file
View file

@ -0,0 +1,29 @@
{
"register": {
"subject": "Pedido de registo recebido",
"content": "Recebemos o pedido de registo. Vamos confirmar assim que possível."
},
"confirm": {
"content": "Olá, sua conta em <a href='{{config.baseurl}}'>{{config.title}}</a> foi confirmada. Escreva para {{config.admin_email}} para obter qualquer informação.",
"subject": "Você pode agora começar a publicar eventos"
},
"event_confirm": {
"content": "Pode confirmar este evento <a href='{{url}}'>nesta página</a>"
},
"test": {
"subject": "A sua configuração SMTP funciona",
"content": "Este é um e-mail de teste, se estiver a ler isto, a sua configuração funciona."
},
"user_confirm": {
"subject": "Você pode agora começar a publicar eventos",
"content": "Olá, a sua conta em <a href='{{config.baseurl}}'>{{config.title}}</a> foi criada. <a href='{{config.baseurl}}/user_confirm/{{user.recover_code}}'>Confirme e escolha uma palavra-passe.</a>."
},
"admin_register": {
"subject": "Novo registo",
"content": "{{user.email}} pediu o registo em {{config.title}}: <br/><pre>{{user.description}}</pre><br/> Confirme <a href='{{config.baseurl}}/admin'>aqui</a>."
},
"recover": {
"subject": "Recuperação da palavra-passe",
"content": "Olá, solicitou a recuperação da sua palavra-passe em {{config.title}}. <a href='{{config.baseurl}}/recover/{{user.recover_code}}'>Clique aqui</a> para confirmar."
}
}

1
locales/email/pt-PT.json Normal file
View file

@ -0,0 +1 @@
{}

View file

@ -8,22 +8,22 @@
"subject": "Você pode agora começar a publicar eventos" "subject": "Você pode agora começar a publicar eventos"
}, },
"event_confirm": { "event_confirm": {
"content": "Você pode confirmar este evento <a href='{{url}}'>nesta página</a>" "content": "Pode confirmar este evento <a href='{{url}}'>nesta página</a>"
}, },
"test": { "test": {
"subject": "Sua configuração SMTP está funcionando", "subject": "A sua configuração SMTP funciona",
"content": "Este é um e-mail de teste, se estiver lendo isto, sua configuração está funcionando." "content": "Este é um e-mail de teste, se estiver a ler isto, a sua configuração funciona."
}, },
"user_confirm": { "user_confirm": {
"subject": "Você pode agora começar a publicar eventos", "subject": "Você pode agora começar a publicar eventos",
"content": "Olá, sua conta em <a href='{{config.baseurl}}'>{{config.title}}</a> foi criada. <a href='{{config.baseurl}}/user_confirm/{{user.recover_code}}'>Confirme e escolha uma senha.</a>." "content": "Olá, a sua conta em <a href='{{config.baseurl}}'>{{config.title}}</a> foi criada. <a href='{{config.baseurl}}/user_confirm/{{user.recover_code}}'>Confirme e escolha uma palavra-passe.</a>."
}, },
"admin_register": { "admin_register": {
"subject": "Novo registro", "subject": "Novo registo",
"content": "{{user.email}} pediu o registro em {{config.title}}: <br/><pre>{{user.description}}</pre><br/> Confirme <a href='{{config.baseurl}}/admin'>aqui</a>." "content": "{{user.email}} pediu o registo em {{config.title}}: <br/><pre>{{user.description}}</pre><br/> Confirme <a href='{{config.baseurl}}/admin'>aqui</a>."
}, },
"recover": { "recover": {
"subject": "Recuperação de senha", "subject": "Recuperação da palavra-passe",
"content": "Olá, você solicitou a recuperação de sua senha em {{config.title}}. <a href='{{config.baseurl}}/recover/{{user.recover_code}}'>Clique aqui</a> para confirmar." "content": "Olá, solicitou a recuperação da sua palavra-passe em {{config.title}}. <a href='{{config.baseurl}}/recover/{{user.recover_code}}'>Clique aqui</a> para confirmar."
} }
} }

View file

@ -104,7 +104,8 @@
"search_coordinates": "Search coordinates", "search_coordinates": "Search coordinates",
"online": "On-line", "online": "On-line",
"test": "Test", "test": "Test",
"show_preview": "Show preview" "show_preview": "Show preview",
"clone": "Clone"
}, },
"login": { "login": {
"description": "By logging in you can publish new events.", "description": "By logging in you can publish new events.",
@ -124,7 +125,8 @@
"insert_your_address": "Enter your e-mail address", "insert_your_address": "Enter your e-mail address",
"feed_description": "To follow updates from a computer or smartphone without the need to periodically open this site, use RSS feeds. </p>\n\n<p> With RSS feeds you use a special app to receive updates from sites that interest you. It's a good way to follow many sites quickly, without the need to create an account or other complications. </p>\n\n<li> If you have Android, we recommend <a href=\"https://f-droid.org/en/packages/net.frju.flym/\">Flym</a> or Feeder </li>\n<li> For iPhone / iPad you can use <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8\"> Feed4U </a> </li>\n<li> For desktop / laptop we recommend Feedbro, to be installed on <a href=\"https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/\"> Firefox </a> or <a href=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa\"> Chrome </a>. </li>\n<br/>\nAdding this link to your RSS feed reader will keep you up to date.", "feed_description": "To follow updates from a computer or smartphone without the need to periodically open this site, use RSS feeds. </p>\n\n<p> With RSS feeds you use a special app to receive updates from sites that interest you. It's a good way to follow many sites quickly, without the need to create an account or other complications. </p>\n\n<li> If you have Android, we recommend <a href=\"https://f-droid.org/en/packages/net.frju.flym/\">Flym</a> or Feeder </li>\n<li> For iPhone / iPad you can use <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8\"> Feed4U </a> </li>\n<li> For desktop / laptop we recommend Feedbro, to be installed on <a href=\"https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/\"> Firefox </a> or <a href=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa\"> Chrome </a>. </li>\n<br/>\nAdding this link to your RSS feed reader will keep you up to date.",
"ical_description": "Computers and smartphones are commonly equipped with a calendar app capable of importing a remote calendar.", "ical_description": "Computers and smartphones are commonly equipped with a calendar app capable of importing a remote calendar.",
"list_description": "If you have a website and want to show a list of events, use the following code" "list_description": "If you have a website and want to show a list of events, use the following code",
"filter_description": "You can filter your export here by tags and place or by a preset collection"
}, },
"register": { "register": {
"description": "Social movements should organize and self-finance.<br/>\n<br/>Before you can publish, <strong> the account must be approved</strong>, consider that <strong> behind this site you will find real people</strong>, so write two lines to let us know what events you would like to publish.", "description": "Social movements should organize and self-finance.<br/>\n<br/>Before you can publish, <strong> the account must be approved</strong>, consider that <strong> behind this site you will find real people</strong>, so write two lines to let us know what events you would like to publish.",
@ -344,7 +346,7 @@
"required": "{fieldName} is required", "required": "{fieldName} is required",
"email": "Insert a valid email", "email": "Insert a valid email",
"latitude": "Insert a valid latitude (-90 < latitude < 90)", "latitude": "Insert a valid latitude (-90 < latitude < 90)",
"longitude": "Insert a valid latitude (-180 < latitude < 180)" "longitude": "Insert a valid longitude (-180 < longitude < 180)"
}, },
"about": "\n <p><a href='https://gancio.org'>Gancio</a> is a shared agenda for local communities.</p>\n ", "about": "\n <p><a href='https://gancio.org'>Gancio</a> is a shared agenda for local communities.</p>\n ",
"oauth": { "oauth": {

View file

@ -106,7 +106,8 @@
"search_coordinates": "Buscar las coordenadas", "search_coordinates": "Buscar las coordenadas",
"online": "En línea", "online": "En línea",
"test": "Prueba", "test": "Prueba",
"show_preview": "Mostrar una vista previa" "show_preview": "Mostrar una vista previa",
"clone": "Clon"
}, },
"login": { "login": {
"description": "Entrando podrás publicar nuevos eventos.", "description": "Entrando podrás publicar nuevos eventos.",
@ -356,7 +357,7 @@
"validators": { "validators": {
"email": "Introduce un correo electrónico valido", "email": "Introduce un correo electrónico valido",
"required": "{fieldName} es requerido", "required": "{fieldName} es requerido",
"longitude": "Introduce una latitud válida (-180 < latitud < 180)", "longitude": "Introduce una longitud válida (-180 < longitud < 180)",
"latitude": "Introduce una latitud válida (-90 < latitud < 90)" "latitude": "Introduce una latitud válida (-90 < latitud < 90)"
}, },
"setup": { "setup": {

View file

@ -1,7 +1,7 @@
{ {
"common": { "common": {
"add_event": "Sortu ekitaldia", "add_event": "Sortu ekitaldia",
"next": "Jarraitu", "next": "Hurrengoa",
"export": "Esportatu", "export": "Esportatu",
"send": "Bidali", "send": "Bidali",
"where": "Non", "where": "Non",
@ -81,7 +81,7 @@
"announcements": "Iragarpenak", "announcements": "Iragarpenak",
"url": "URLa", "url": "URLa",
"place": "Lekua", "place": "Lekua",
"label": "Izena", "label": "Etiketa",
"max_events": "Gehienezko ekitaldi kopurua", "max_events": "Gehienezko ekitaldi kopurua",
"import": "Inportatu", "import": "Inportatu",
"reset": "Berrezarri", "reset": "Berrezarri",
@ -99,7 +99,14 @@
"recurring_event_actions": "Ekitaldi errepikarien eragiketak", "recurring_event_actions": "Ekitaldi errepikarien eragiketak",
"content": "Edukia", "content": "Edukia",
"admin_actions": "Administratzaile eragiketak", "admin_actions": "Administratzaile eragiketak",
"tag": "Etiketa" "tag": "Etiketa",
"latitude": "Latitudea",
"longitude": "Longitudea",
"search_coordinates": "Bilbatu koordenatuak",
"online": "Online",
"test": "Proba",
"show_preview": "Erakutsi aurrebista",
"clone": "Klonatu"
}, },
"login": { "login": {
"description": "Saioa hasten baduzu ekitaldi berriak sortu ahal izango dituzu.", "description": "Saioa hasten baduzu ekitaldi berriak sortu ahal izango dituzu.",
@ -181,7 +188,10 @@
"address_description_osm": "Bilatu koordenatuak helbidea idatziz. (<a href='http://osm.org/copyright'>OpenStreetMap</a> kolaboratzaileak)", "address_description_osm": "Bilatu koordenatuak helbidea idatziz. (<a href='http://osm.org/copyright'>OpenStreetMap</a> kolaboratzaileak)",
"show_multidate": "data anitzeko ekitaldiak", "show_multidate": "data anitzeko ekitaldiak",
"where_advanced_options": "Lekua - Aukera aurreratuak", "where_advanced_options": "Lekua - Aukera aurreratuak",
"where_advanced_options_description": "Zehaztu hemen lekuaren ezaugarri gehigarriak" "where_advanced_options_description": "Zehaztu hemen lekuaren ezaugarri gehigarriak",
"online_locations_help": "Esaterako bideokonferentzia baten URLa eta URL alternatiboa (gehienez 3)",
"online_locations": "Online kokapenak",
"online_locations_fallback_urls": "Esteka alternatiboak"
}, },
"admin": { "admin": {
"place_description": "Lekua edo helbidea oker badago, alda dezakezu.<br/>Leku honekin lotutako iraganeko eta etorkizuneko ekitaldien helbidea aldatuko da.", "place_description": "Lekua edo helbidea oker badago, alda dezakezu.<br/>Leku honekin lotutako iraganeko eta etorkizuneko ekitaldien helbidea aldatuko da.",
@ -297,7 +307,10 @@
"geocoding_test_success": "Geokodeketa zerbitzua {service_name}-(e)n martxan dago", "geocoding_test_success": "Geokodeketa zerbitzua {service_name}-(e)n martxan dago",
"tilelayer_test_success": "Lauza-geruzen zerbitzua {service_name}(e)n martxan dago", "tilelayer_test_success": "Lauza-geruzen zerbitzua {service_name}(e)n martxan dago",
"colors": "Koloreak", "colors": "Koloreak",
"edit_tag": "Editatu etiketa" "edit_tag": "Editatu etiketa",
"allow_online_event_hint": "URLak eskatu ",
"allow_online_event": "Online ekitaldiak ahalbidetu",
"delete_tag_confirm": "Ziur al zaude \"{tag}\" etiketa ezabatu nahi duzula? Etiketa {n} ekitalditik ezabatuko da."
}, },
"auth": { "auth": {
"not_confirmed": "Oraindik baieztatu gabe dago…", "not_confirmed": "Oraindik baieztatu gabe dago…",
@ -338,7 +351,9 @@
}, },
"validators": { "validators": {
"email": "Sartu baliozko eposta bat", "email": "Sartu baliozko eposta bat",
"required": "{fieldName} beharrezkoa da" "required": "{fieldName} beharrezkoa da",
"latitude": "Sartu baliozko latitude bat (-90 < latitudea < 90)",
"longitude": "Sartu baliozko longitudea bat (-180 < longitudea < 180)"
}, },
"setup": { "setup": {
"start": "Hasi", "start": "Hasi",

View file

@ -102,12 +102,17 @@
"tag": "Tag", "tag": "Tag",
"admin_actions": "Admin actions", "admin_actions": "Admin actions",
"recurring_event_actions": "Evènement Récurrent action", "recurring_event_actions": "Evènement Récurrent action",
"content": "Contenu" "content": "Contenu",
"online": "En ligne",
"search_coordinates": "Rechercher les coordonnées",
"test": "Tester",
"show_preview": "Afficher l'aperçu",
"clone": "Cloner"
}, },
"event": { "event": {
"follow_me_description": "Une des manières de rester informé sur les évènements publiés ici sur {title}\nest de suivre le compte <u>{account}</u> sur le fediverse, par exemple via Mastodon, et pourquoi pas d'ajouter des ressources à un évènement à partir de là.<br/><br/>\nSi vous n'avez jamais entendu parler de Mastodon and du fediverse, nous vous recommandons de lire <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>cet article (en anglais)</a>.<br/><br/>Saisissez votre nom d'instance ci-dessous (par ex. mastodon.social)", "follow_me_description": "Une des manières de rester informé sur les évènements publiés ici sur {title}\nest de suivre le compte <u>{account}</u> sur le fediverse, par exemple via Mastodon, et pourquoi pas d'ajouter des ressources à un évènement à partir de là.<br/><br/>\nSi vous n'avez jamais entendu parler de Mastodon and du fediverse, nous vous recommandons de lire <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>cet article (en anglais)</a>.<br/><br/>Saisissez votre nom d'instance ci-dessous (par ex. mastodon.social)",
"interact_with_me_at": "Interagissez avec moi sur le fediverse à", "interact_with_me_at": "Interagissez avec moi sur le fediverse à",
"recurrent_1m_ordinal": "Le {n} {days} de chaque mois", "recurrent_1m_ordinal": "Chaque {n} {days} du mois",
"import_ICS": "Importer à partir d'un fichier ICS", "import_ICS": "Importer à partir d'un fichier ICS",
"import_URL": "Importer à partir d'une URL", "import_URL": "Importer à partir d'une URL",
"remove_recurrent_confirmation": "Êtes-vous sûr·e de vouloir supprimer cet évènement récurrent ?\nLes évènements passés seront conservés, mais aucun évènement futur de sera créé.", "remove_recurrent_confirmation": "Êtes-vous sûr·e de vouloir supprimer cet évènement récurrent ?\nLes évènements passés seront conservés, mais aucun évènement futur de sera créé.",
@ -145,7 +150,7 @@
"anon": "Anonyme", "anon": "Anonyme",
"ics": "ICS", "ics": "ICS",
"each_2w": "Une semaine sur deux", "each_2w": "Une semaine sur deux",
"recurrent_2m_ordinal": "Les {n} {days} du mois un mois sur deux", "recurrent_2m_ordinal": "Chaque {n} {days} par mois un mois sur deux",
"recurrent_2m_days": "Le {days} un mois sur deux", "recurrent_2m_days": "Le {days} un mois sur deux",
"recurrent_2w_days": "Un {days} sur deux", "recurrent_2w_days": "Un {days} sur deux",
"edit_recurrent": "Modifier lévènement récurrent :", "edit_recurrent": "Modifier lévènement récurrent :",
@ -157,8 +162,14 @@
"download_flyer": "Télécharger le flyer", "download_flyer": "Télécharger le flyer",
"show_multidate": "évènements sur plusieurs jours", "show_multidate": "évènements sur plusieurs jours",
"choose_focal_point": "Choisir le centre d'intérêt", "choose_focal_point": "Choisir le centre d'intérêt",
"address_description_osm": "Quelle est l'adresse? (<a href='http://osm.org/copyright'>OpenStreetMap</a> contributeurs)", "address_description_osm": "Chercher des coordonnées en tapant l'adresse. (<a href='http://osm.org/copyright'>OpenStreetMap</a> contributeurs)",
"address_description": "Quelle adresse ?" "address_description": "Quelle adresse ?",
"where_advanced_options": "Lieu - Option avancées",
"online_locations_fallback_urls": "Liens alternatifs",
"where_advanced_options_description": "Définir ici les propriétés additionnelles du lieu",
"online_locations": "Localisations en ligne",
"online_locations_help": "Par exemple l'URL d'un salon de visioconférence et une URL alternative (max. 3)",
"address_geocoded_disclaimer": "Si vous ne pouvez pas trouver l'<strong>adresse</strong> our le <strong>numéro</strong> que vous cherchez dans les résultats de géocodage, vous pouvez les insérer manuellement dans le champ 'Adresse' sans coordonnées précises. Par ailleurs considérez que le projet <a target=\"_blank\" href=\"https://www.openstreetmap.org/\">OpenStreetMap</a> est ouvert aux contributions pour corriger cela. Si vous avez un téléphone Android, nous recommendons <a target=\"_blank\" href=\"https://f-droid.org/en/packages/de.westnordost.streetcomplete/\">StreetComplete</a> "
}, },
"register": { "register": {
"description": "Les mouvements sociaux doivent s'organiser et s'autofinancer.<br/>\n<br/>Avant de pouvoir publier, <strong> le compte doit être approuvé</strong>, considérez que <strong> derrière ce site vous trouverez de vraies personnes</strong>, à qui vous pouvez écrire en deux lignes pour exprimer les évènements que vous souhaiteriez publier.", "description": "Les mouvements sociaux doivent s'organiser et s'autofinancer.<br/>\n<br/>Avant de pouvoir publier, <strong> le compte doit être approuvé</strong>, considérez que <strong> derrière ce site vous trouverez de vraies personnes</strong>, à qui vous pouvez écrire en deux lignes pour exprimer les évènements que vous souhaiteriez publier.",
@ -265,7 +276,7 @@
"config_plugin": "Configuration du plugin", "config_plugin": "Configuration du plugin",
"colors": "Couleurs", "colors": "Couleurs",
"allow_multidate_event": "Autoriser les évènements sur plusieurs jours", "allow_multidate_event": "Autoriser les évènements sur plusieurs jours",
"delete_tag_confirm": "Etes vous certain.e de vouloir supprimer le tag \"{tag}\"? Le tag sera supprimé de {n} évènements.", "delete_tag_confirm": "Êtes vous certain.e de vouloir supprimer le tag \"{tag}\"? Le tag sera supprimé de {n} évènements.",
"hide_thumbs": "Cacher les vignettes", "hide_thumbs": "Cacher les vignettes",
"hide_calendar": "Cacher le calendrier", "hide_calendar": "Cacher le calendrier",
"default_images": "Images par défaut", "default_images": "Images par défaut",
@ -288,9 +299,13 @@
"geolocation": "Géolocalisation", "geolocation": "Géolocalisation",
"edit_tag_help": "Vous pouvez changer le tag en le remplaçant par un nouveau ou bien fusionner celui-ci avec l'existant. Les {n} évènements associés seront modifiés.", "edit_tag_help": "Vous pouvez changer le tag en le remplaçant par un nouveau ou bien fusionner celui-ci avec l'existant. Les {n} évènements associés seront modifiés.",
"edit_tag": "Modifier le tag", "edit_tag": "Modifier le tag",
"delete_collection_confirm": "Etes vous certain.e de vouloir supprimer la collection <u>{collection}</u>?", "delete_collection_confirm": "Êtes vous certain⋅e de vouloir supprimer la collection <u>{collection}</u>?",
"admin_email_help": "L'adresse que nous utilisons comme expéditeur pour envoyer des courriels. Il s'agit également de l'adresse à laquelle les mails admin sont envoyés.", "admin_email_help": "L'adresse que nous utilisons comme expéditeur pour envoyer des courriels. Il s'agit également de l'adresse à laquelle les mails admin sont envoyés.",
"geolocation_description": "<b>1. Définir un fournisseur de service de géolocalisation</b>.<br>Actuellement, parmi ceux listés dans le <a href=\"https://wiki.openstreetmap.org/wiki/Nominatim#Alternatives_.2F_Third-party_providers\">wiki d'OpenStreetMap</a>, il y a un service de support pour logiciel <a href=\"https://github.com/osm-search/Nominatim\">Nominatim</a> et <a href=\"https://github.com/komoot/photon\">Photon</a>.<br>Vous pouvez utiliser l'une des démos officielles en copiant le lien dans le champs ' Geocoding provider' :<ul><li>https://nominatim.openstreetmap.org/search (<a href=\"https://operations.osmfoundation.org/policies/nominatim/\">Terms of Service</a>)</li><li>https://photon.komoot.io/api/ (<a href=\"https://photon.komoot.io/\">Terms of Service</a>)</li></ul><br><b>2. Definir un fournisseur de fonds de carte.</b><br>Vous pouvez en trouvez une liste ici: <a href=\"https://leaflet-extras.github.io/leaflet-providers/preview/\">https://leaflet-extras.github.io/leaflet-providers/preview/</a>" "geolocation_description": "<b>1. Définir un fournisseur de service de géolocalisation</b>.<br>Actuellement, parmi ceux listés dans le <a href=\"https://wiki.openstreetmap.org/wiki/Nominatim#Alternatives_.2F_Third-party_providers\">wiki d'OpenStreetMap</a>, il y a un service de support pour logiciel <a href=\"https://github.com/osm-search/Nominatim\">Nominatim</a> et <a href=\"https://github.com/komoot/photon\">Photon</a>.<br>Vous pouvez utiliser l'une des démos officielles en copiant le lien dans le champs ' Fournisseurs de géocodage' :<ul><li>https://nominatim.openstreetmap.org/search (<a href=\"https://operations.osmfoundation.org/policies/nominatim/\">Conditions d'utilisations</a>)</li><li>https://photon.komoot.io/api/ (<a href=\"https://photon.komoot.io/\">Conditions d'utilisations</a>)</li></ul><br><b>2. Définir un fournisseur de fonds de carte.</b><br>Vous pouvez en trouvez une liste ici: <a href=\"https://leaflet-extras.github.io/leaflet-providers/preview/\">https://leaflet-extras.github.io/leaflet-providers/preview/</a>",
"header_image": "Image d'en-tête",
"allow_online_event_hint": "Demander des liens ",
"fallback_image": "Image de rechange",
"allow_online_event": "Permettre les évènements en ligne"
}, },
"oauth": { "oauth": {
"scopes": { "scopes": {
@ -302,15 +317,17 @@
"about": "\n <p><a href='https://gancio.org'>Gancio</a> est un agenda partagé pour les communautés locales.</p>\n ", "about": "\n <p><a href='https://gancio.org'>Gancio</a> est un agenda partagé pour les communautés locales.</p>\n ",
"validators": { "validators": {
"email": "Saisissez une adresse courriel valide", "email": "Saisissez une adresse courriel valide",
"required": "{fieldName} est requis" "required": "{fieldName} est requis",
"latitude": "Insérer une latitude valide (entre -90 et 90)",
"longitude": "Insérer une longitude valide (entre -180 et 180)"
}, },
"ordinal": { "ordinal": {
"-1": "dernier", "1": "premier",
"5": "cinquième",
"4": "quatrième",
"3": "troisième",
"2": "deuxième", "2": "deuxième",
"1": "premier" "3": "troisième",
"4": "quatrième",
"5": "cinquième",
"-1": "dernier"
}, },
"confirm": { "confirm": {
"valid": "Votre compte a bien été confirmé, vous pouvez désormais <a href=\"/login\">vous connecter</a>", "valid": "Votre compte a bien été confirmé, vous pouvez désormais <a href=\"/login\">vous connecter</a>",

View file

@ -28,7 +28,7 @@
"feed_url_copied": "Abrir o URL da fonte copiado no teu lector de RSS", "feed_url_copied": "Abrir o URL da fonte copiado no teu lector de RSS",
"event": "Evento", "event": "Evento",
"pause": "Pausa", "pause": "Pausa",
"start": "Inicio", "start": "Comezar",
"fediverse": "Fediverso", "fediverse": "Fediverso",
"announcements": "Anuncios", "announcements": "Anuncios",
"reset": "Restablecer", "reset": "Restablecer",
@ -102,11 +102,12 @@
"content": "Contido", "content": "Contido",
"admin_actions": "Accións de Admin", "admin_actions": "Accións de Admin",
"recurring_event_actions": "Accións de eventos recurrentes", "recurring_event_actions": "Accións de eventos recurrentes",
"tag": "Etiqueta", "tag": "Etiquetar",
"search_coordinates": "Buscar coordenadas", "search_coordinates": "Buscar coordenadas",
"online": "En liña", "online": "En liña",
"show_preview": "Mostrar vista previa", "show_preview": "Mostrar vista previa",
"test": "Proba" "test": "Proba",
"clone": "Clonar"
}, },
"recover": { "recover": {
"not_valid_code": "Algo fallou." "not_valid_code": "Algo fallou."
@ -170,7 +171,7 @@
"image_too_big": "A imaxe non pode superar os 4MB", "image_too_big": "A imaxe non pode superar os 4MB",
"recurrent_1m_days": "O {days} de cada mes", "recurrent_1m_days": "O {days} de cada mes",
"each_2w": "Cada dúas semanas", "each_2w": "Cada dúas semanas",
"follow_me_description": "Un dos xeitos de recibir actualizacións dos eventos que se publican aquí en {title},\né seguindo a conta <u>{account}</u> no fediverso, por exemplo a través de Mastodon, e posiblemente tamén engadir recursos para un evento desde alí.<br/><br/>\nSe nunco escoitaches falar de Mastodon e o fediverso recomendámosche ler <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>este artigo</a>.<br/><br/>Escribe aquí a túa instancia (ex. mastodon.social)", "follow_me_description": "Un dos xeitos de recibir actualizacións dos eventos que se publican aquí en {title},\né seguindo a conta <u>{account}</u> no fediverso, por exemplo a través de Mastodon, e posiblemente tamén engadir recursos para un evento desde alí.<br/><br/>\nSe non escoitaches falar de Mastodon e o fediverso recomendámosche ler <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>este artigo</a>.<br/><br/>Escribe aquí a túa instancia (ex. mastodon.social)",
"ics": "ICS", "ics": "ICS",
"import_description": "Podes importar eventos desde outras plataformas e outras instancias usando formatos estándar (ics e h-event)", "import_description": "Podes importar eventos desde outras plataformas e outras instancias usando formatos estándar (ics e h-event)",
"alt_text_description": "Descrición para persoas con problemas de visión", "alt_text_description": "Descrición para persoas con problemas de visión",
@ -241,11 +242,11 @@
"instance_locale": "Idioma por defecto", "instance_locale": "Idioma por defecto",
"delete_announcement_confirm": "Tes a certeza de querer eliminar o anuncio?", "delete_announcement_confirm": "Tes a certeza de querer eliminar o anuncio?",
"instance_locale_description": "Idioma preferido para as páxinas. A veces as mensaxes teñen que mostrarse no mesmo idioma para tódalas persoas (por exemplo cando publicas vía ActivityPub ou cando envías os emails). Nestos casos usarase o idioma elexido aquí arriba.", "instance_locale_description": "Idioma preferido para as páxinas. A veces as mensaxes teñen que mostrarse no mesmo idioma para tódalas persoas (por exemplo cando publicas vía ActivityPub ou cando envías os emails). Nestos casos usarase o idioma elexido aquí arriba.",
"enable_trusted_instances": "Activar instancias amigas", "enable_trusted_instances": "Activar instancias amigables",
"trusted_instances_help": "A lista das instancias amigas será mostrada na cabeceira", "trusted_instances_help": "A lista das instancias recomendadas será mostrada na cabeceira",
"trusted_instances_label": "Etiqueta de navegação para instâncias de amigos", "trusted_instances_label": "Etiqueta de navegación para instancias recomendadas",
"trusted_instances_label_default": "Casos amigáveis", "trusted_instances_label_default": "Instancias amigables",
"trusted_instances_label_help": "A etiqueta padrão é 'Instâncias amigáveis'", "trusted_instances_label_help": "A etiqueta por defecto é 'Instáncias amigables'",
"delete_trusted_instance_confirm": "Tes a certeza de querer eliminar este elemento do menú de instancias amigas?", "delete_trusted_instance_confirm": "Tes a certeza de querer eliminar este elemento do menú de instancias amigas?",
"instance_place_help": "A etiqueta a mostrar nas instancias de outras", "instance_place_help": "A etiqueta a mostrar nas instancias de outras",
"add_link": "Engadir ligazón", "add_link": "Engadir ligazón",
@ -316,7 +317,7 @@
"settings": { "settings": {
"change_password": "Cambia o contrasinal", "change_password": "Cambia o contrasinal",
"danger_section": "Sección perigosa", "danger_section": "Sección perigosa",
"remove_account": "Ao premer o seguinte botón vas eliminar túa conta de usuaria. Os eventos que publicaches permanecerán.", "remove_account": "Ao premer o seguinte botón vas eliminar túa conta. Os eventos que publicaches permanecerán.",
"password_updated": "Contrasinal cambiado.", "password_updated": "Contrasinal cambiado.",
"remove_account_confirm": "Vas eliminar permanentemente a túa conta", "remove_account_confirm": "Vas eliminar permanentemente a túa conta",
"update_confirm": "Queres gardar as modificacións?" "update_confirm": "Queres gardar as modificacións?"
@ -332,11 +333,11 @@
}, },
"ordinal": { "ordinal": {
"1": "primeiro", "1": "primeiro",
"2": "segundo",
"3": "terceiro", "3": "terceiro",
"4": "cuarto", "4": "cuarto",
"5": "quinto", "5": "quinto",
"-1": "último", "-1": "último"
"2": "segundo"
}, },
"validators": { "validators": {
"required": "{fieldName} é requerido", "required": "{fieldName} é requerido",

View file

@ -1,5 +1,6 @@
module.exports = { module.exports = {
ca: 'Català', ca: 'Català',
cs: 'Czech',
de: 'Deutsch', de: 'Deutsch',
en: 'English', en: 'English',
es: 'Español', es: 'Español',
@ -11,6 +12,7 @@ module.exports = {
nl: 'Dutch', nl: 'Dutch',
pl: 'Polski', pl: 'Polski',
pt: 'Português', pt: 'Português',
'pt-BR': 'Português (Brasilian)',
ru: 'Русский', ru: 'Русский',
sk: 'Slovak', sk: 'Slovak',
zh: '中国' zh: '中国'

View file

@ -105,7 +105,7 @@
"search_coordinates": "Cerca coordinate", "search_coordinates": "Cerca coordinate",
"online": "Online", "online": "Online",
"show_preview": "Mostra anteprima", "show_preview": "Mostra anteprima",
"test": "Prova" "clone": "Clona"
}, },
"login": { "login": {
"description": "Entrando puoi pubblicare nuovi eventi.", "description": "Entrando puoi pubblicare nuovi eventi.",
@ -343,7 +343,7 @@
"required": "Campo {fieldName} necessario", "required": "Campo {fieldName} necessario",
"email": "Inserisci un'e-mail valida", "email": "Inserisci un'e-mail valida",
"latitude": "Inserisci una latitudine valida (-90 < latitudine < 90)", "latitude": "Inserisci una latitudine valida (-90 < latitudine < 90)",
"longitude": "Inserisci una latitudine valida (-180 < latitude < 180)" "longitude": "Inserisci una longitudine valida (-180 < longitudine < 180)"
}, },
"about": "\n <p> <a href='https://gancio.org'> Gancio </a> è un'agenda condivisa per le comunità locali. </p>\n ", "about": "\n <p> <a href='https://gancio.org'> Gancio </a> è un'agenda condivisa per le comunità locali. </p>\n ",
"oauth": { "oauth": {

View file

@ -242,7 +242,8 @@
"show_map": "Vis kart", "show_map": "Vis kart",
"latitude": "breddegrad", "latitude": "breddegrad",
"longitude": "Lengdegrad", "longitude": "Lengdegrad",
"getting_there": "Slik kommer du deg dit" "getting_there": "Slik kommer du deg dit",
"clone": "Klone"
}, },
"about": "\n <p><a href='https://gancio.org'>Gancio</a> er en delt agenda for lokale gemenskaper.</p>\n ", "about": "\n <p><a href='https://gancio.org'>Gancio</a> er en delt agenda for lokale gemenskaper.</p>\n ",
"validators": { "validators": {
@ -250,12 +251,12 @@
"required": "{fieldName} kreves" "required": "{fieldName} kreves"
}, },
"ordinal": { "ordinal": {
"-1": "siste", "1": "første",
"5": "femte",
"4": "fjerde",
"3": "tredje",
"2": "andre", "2": "andre",
"1": "første" "3": "tredje",
"4": "fjerde",
"5": "femte",
"-1": "siste"
}, },
"export": { "export": {
"list_description": "Hvis du har en nettside og ønsker å vise en liste over hendelser, bruk følgende kode", "list_description": "Hvis du har en nettside og ønsker å vise en liste over hendelser, bruk følgende kode",

View file

@ -104,12 +104,12 @@
"tilelayer_test_button": "Tilelayer testen" "tilelayer_test_button": "Tilelayer testen"
}, },
"ordinal": { "ordinal": {
"4": "vierde",
"1": "eerste", "1": "eerste",
"3": "derde",
"-1": "laatste",
"2": "tweede", "2": "tweede",
"5": "vijfde" "3": "derde",
"4": "vierde",
"5": "vijfde",
"-1": "laatste"
}, },
"common": { "common": {
"plugins": "Plugins", "plugins": "Plugins",
@ -210,7 +210,8 @@
"reset": "Resetten", "reset": "Resetten",
"import": "Importeren", "import": "Importeren",
"label": "Label", "label": "Label",
"collections": "Collecties" "collections": "Collecties",
"clone": "Kloon"
}, },
"login": { "login": {
"not_registered": "Niet geregistreerd?", "not_registered": "Niet geregistreerd?",

View file

@ -64,7 +64,8 @@
"embed": "Osadź", "embed": "Osadź",
"embed_help": "Skopiuj poniższy kod na swoją stronę internetową, a wydarzenie będzie wyglądało tak jak tutaj", "embed_help": "Skopiuj poniższy kod na swoją stronę internetową, a wydarzenie będzie wyglądało tak jak tutaj",
"feed": "Kanał RSS", "feed": "Kanał RSS",
"feed_url_copied": "Otwórz skopiowany link w swoim czytniku RSS" "feed_url_copied": "Otwórz skopiowany link w swoim czytniku RSS",
"clone": "Klon"
}, },
"settings": { "settings": {
"change_password": "Zmień swoje hasło", "change_password": "Zmień swoje hasło",
@ -75,11 +76,11 @@
}, },
"ordinal": { "ordinal": {
"1": "pierwszy", "1": "pierwszy",
"5": "piąty",
"-1": "ostatni",
"2": "drugi", "2": "drugi",
"3": "trzeci", "3": "trzeci",
"4": "czwarty" "4": "czwarty",
"5": "piąty",
"-1": "ostatni"
}, },
"confirm": { "confirm": {
"not_valid": "Coś poszło nie tak.", "not_valid": "Coś poszło nie tak.",

356
locales/pt-BR.json Normal file
View file

@ -0,0 +1,356 @@
{
"common": {
"add_event": "Adicionar evento",
"description": "Descrição",
"send": "Enviar",
"address": "Endereço",
"next": "Próximo",
"when": "Quando",
"where": "Onde",
"login": "Login",
"export": "Exportar",
"email": "E-mail",
"what": "O que",
"media": "Media",
"password": "Senha",
"register": "Registrar",
"remove": "Remover",
"confirm": "Confirmar",
"events": "Eventos",
"settings": "Opções",
"actions": "Ações",
"edit": "Editar",
"admin": "Admin",
"places": "Lugares",
"hide": "Ocultar",
"search": "Buscar",
"info": "Info",
"users": "Usuárias",
"share": "Compartilhar",
"name": "Nome",
"associate": "Associar",
"logout": "Sair",
"remove_admin": "Remover admin",
"activate": "Ativar",
"save": "Salvar",
"preview": "Visualizar",
"edit_event": "Editar evento",
"add": "Adicionar",
"copy": "Copiar",
"ok": "Ok",
"cancel": "Cancelar",
"me": "Você",
"password_updated": "Senha alterada.",
"resources": "Recursos",
"activate_user": "Confirmado",
"copy_link": "Copiar link",
"send_via_mail": "Enviar e-mail",
"add_to_calendar": "Adicionar ao calendário",
"copied": "Copiado",
"recover_password": "Recuperar senha",
"new_password": "Nova senha",
"new_user": "Nova usuária",
"deactivate": "Desligar",
"related": "Relacionado",
"enable": "Habilitar",
"disable": "Desabilitar",
"federation": "Federação",
"set_password": "Definir senha",
"instances": "Instâncias",
"follow": "Seguir",
"moderation": "Moderação",
"user": "Usuária",
"authorize": "Autorizar",
"title": "Título",
"filter": "Filtro",
"event": "Evento",
"pause": "Pausar",
"start": "Início",
"feed": "Feed RSS",
"skip": "Pular",
"delete": "Remover",
"fediverse": "Fediverso",
"announcements": "Anúncios",
"place": "Local",
"url": "URL",
"logout_ok": "Deslogado",
"n_resources": "nenhum recurso|um recurso|{n} recursos",
"embed": "Incorporar",
"embed_title": "Incorpore este evento em sua página",
"embed_help": "Copie o seguinte código em sua página e o evento será exibido desta maneira",
"displayname": "Nome de exibição",
"feed_url_copied": "Abra a URL copiada do feed em seu leitor de RSS",
"follow_me_title": "Siga as atualizações pelo Fediverso",
"tags": "Tags",
"theme": "Tema",
"reset": "Reiniciar",
"import": "Importar",
"collections": "Coleções",
"max_events": "N. máximo de eventos",
"label": "Etiqueta",
"close": "Fechar",
"plugins": "Plugins",
"help_translate": "Ajude a traduzir",
"show_map": "Exibir mapa",
"calendar": "Calendário",
"home": "Início",
"about": "Sobre",
"content": "Conteúdo",
"admin_actions": "Ações de admin",
"recurring_event_actions": "Ações para eventos recorrentes",
"tag": "Tag",
"latitude": "Latitude",
"longitude": "Longitude",
"search_coordinates": "Procurar coordenadas",
"online": "On-line",
"test": "Teste",
"show_preview": "Mostrar pré-visualização",
"clone": "Clone"
},
"admin": {
"user_block_confirm": "Têm a certeza que quer bloquear o utilizador {user}?",
"filter_instances": "Filtrar domínios",
"user_add_help": "Um e-mail com instruções para confirmar a inscrição e escolher uma senha será enviada ao novo usuário",
"show_resource": "Mostrar recurso",
"block_user": "Bloquear utilizador",
"filter_users": "Filtrar utilizadores",
"hide_resource": "Ocultar recurso",
"delete_resource": "Remover recurso",
"delete_resource_confirm": "Têm a certeza que quer remover este recurso?",
"show_smtp_setup": "Configurações de e-mail",
"resources": "Recursos",
"delete_announcement_confirm": "Têm a certeza que quer remover o anúncio?",
"smtp_hostname": "Hostname do SMTP",
"collections_description": "Coleções são agrupamentos de eventos por marcadores e locais. Eles serão exibidos na página principal",
"new_collection": "Nova coleção",
"disable_admin_user_confirm": "Têm a certeza que quer remover permissões de administração de {user}?",
"enable_admin_user_confirm": "Têm a certeza que quer adicionar permissões de administrador para {user}?",
"event_remove_ok": "Evento removido",
"smtp_description": "<ul><li>Administrador deve receber um e-mail quando um evento anónimo for adicionado (se habilitado).</li><li>Administrador deve receber um e-mail de requisição de registo (se habilitado).</li><li>Utilizador deve receber um e-mail de solicitação de registro.</li><li>Utilizador deve receber um e-mail de confirmação de registo.</li><li>Utilizador deve receber um e-mail de confirmação quando registado diretamente por um administrador.</li><li>Utilizadores devem receber um e-mail para recuperar a senha quando eles esquecerem ela</li></ul>",
"allow_registration_description": "Permitir registo aberto de utilizadores?",
"block": "Bloquear",
"unblock": "Desbloquear",
"instance_name": "Nome da instância",
"favicon": "Logo",
"instance_block_confirm": "Têm a certeza que quer bloquear o domínio {instance}?",
"enable_federation": "Habilitar federação",
"enable_federation_help": "Será possível seguir está instância a partir do Fediverso",
"add_instance": "Adicionar instância",
"hide_boost_bookmark_help": "Ocultar os pequenos ícones mostrando o número de impulsos e favoritos vindos do Fediverso",
"announcement_remove_ok": "Anúncio removido",
"instance_timezone_description": "Gancio é desenvolvido para coletar os eventos de um local específico, como uma cidade. Todos os eventos nesse local serão exibidos no fuso-horário escolhido para ele.",
"instance_locale_description": "Idioma de preferência para as páginas. Algumas vezes as mensagens precisam ser exibidas em um mesmo idioma para todos (por exemplo, quando publicando através do ActivityPub ou quando enviar alguns e-mails). Nestes casos o idioma seleciona abaixo será o utilizado.",
"title_description": "É utilizado no título da página, no assunto do e-mail para exportar feeds RSS e ICS.",
"instance_name_help": "Conta ActivityPub para seguir",
"enable_trusted_instances": "Habilitar domínios amigáveis",
"trusted_instances_help": "A lista de domínios amigáveis será exibido no cabeçalho",
"trusted_instances_label": "Etiqueta de navegação para domínios amigos",
"trusted_instances_label_default": "Domínios amigos",
"trusted_instances_label_help": "A etiqueta padrão é 'Domínios amigos'",
"add_trusted_instance": "Adicione um domínio amigável",
"footer_links": "Links de rodapé",
"delete_footer_link_confirm": "Têm a certeza que quer remover este link?",
"edit_place": "Editar local",
"smtp_port": "Porta do SMTP",
"smtp_secure": "SMTP Seguro (TLS ou STARTTLS)",
"smtp_use_sendmail": "Utilizar sendmail",
"instance_place_help": "A etiqueta para exibir em outros domínios",
"delete_trusted_instance_confirm": "Quer realmente remover este item do menu de domínios amigos?",
"sender_email": "E-mail do remetente",
"widget": "Widget",
"wrong_domain_warning": "O baseurl configurado no config.json <b>({baseurl})</b> é diferente do que está a usar para visitar <b>({url})</b>",
"edit_collection": "Editar Coleção",
"enable_resources_help": "Permitir adicionar recursos para o evento a partir do Fediverso",
"hide_boost_bookmark": "Ocultar impulsos/favoritos",
"select_instance_timezone": "Fuso horário",
"instance_locale": "Idioma padrão",
"enable_resources": "Habilitar recursos",
"delete_user": "Remover",
"remove_admin": "Remover administrador",
"place_description": "Se colocou o local ou o endereço errado, pode alterá-lo.<br/>Todos os eventos atuais e passados associados com este local terão o endereço alterado.",
"event_confirm_description": "Pode confirmar eventos criados por utilizadores anónimos aqui",
"disable_user_confirm": "Têm a certeza que quer desativar {user}?",
"delete_user_confirm": "Têm a certeza que quer remover {user}?",
"user_remove_ok": "Usuário removido",
"user_create_ok": "Usuário criado",
"allow_anon_event": "Permitir eventos anônimos (precisam ser confirmados)?",
"allow_recurrent_event": "Permitir eventos recorrentes",
"recurrent_event_visible": "Exibir eventos recorrentes por padrão",
"user_blocked": "Utilizador {user} bloqueado",
"announcement_description": "Nesta secção pode inserir anúncios que serão exibidos na página principal",
"description_description": "Exibido no cabeçalho próximo ao título",
"instance_place": "Local indicativo deste domínio",
"is_dark": "Tema escuro",
"add_link": "Adicionar link",
"new_announcement": "Novo anúncio",
"federation": "Federação / ActivityPub",
"smtp_test_success": "Um e-mail de teste foi enviado para {admin_email}, por favor verifique sua caixa de entrada",
"smtp_test_button": "Enviar e-mail de teste",
"allow_geolocation": "Permitir geolocalização de eventos",
"config_plugin": "Configuração da extensão",
"fallback_image": "Imagem alternativa",
"header_image": "Imagem de cabeçalho",
"hide_thumbs": "Ocultar miniaturas",
"default_images_help": "Precisa de <a href='/admin?tab=theme'>recarregar</a> a página para ver as mudanças.",
"domain": "Domínio",
"default_images": "Imagens padrão",
"known_users": "Utilizadores conhecidos",
"created_at": "Criado em",
"hide_calendar": "Ocultar calendário",
"blocked": "Bloqueado",
"admin_email": "E-mail do admin",
"tilelayer_provider_attribution": "Atribuição",
"geolocation": "Geolocalização",
"edit_tag": "Editar etiqueta",
"allow_online_event": "Permitir eventos online",
"allow_online_event_hint": "Pedir por links ",
"admin_email_help": "O e-mail que utilizaremos como remetente para enviar mensagens. Este é também o endereço para o qual são enviadas as mensagens da administração",
"allow_multidate_event": "Permitir eventos com múltiplas datas",
"delete_tag_confirm": "Tem certeza que quer remover a etiqueta \"{tag}\"? A etiqueta será removida de {n} eventos.",
"delete_collection_confirm": "Têm a certeza que quer remover a coleção <u>{collection}</u>?",
"colors": "Cores",
"geocoding_provider_help": "O provedor padrão é o Nominatim",
"geocoding_provider_type_help": "O software padrão é o Nominatim",
"geocoding_countrycodes": "Código de países",
"geocoding_provider_type": "Software de geocodificação",
"geocoding_provider": "Provedor de geocodificação",
"tilelayer_provider_help": "O provedor padrão é o OpenStreetMap",
"edit_tag_help": "Você pode alterar o marcador ao substituí-lo por um novo ou mesclando-o com um já existente. Os {n} eventos associados também serão alterados."
},
"event": {
"follow_me_description": "Uma das maneiras de se manter atualizado com os eventos publicados aqui em {title},\né seguir a conta <u>{account}</u> no Fediverso, por exemplo, via Mastodon, e possivelmente adicionar recursos para um evento a partir de lá.<br/><br/>\nSe nunca ouviu falar sobre Mastodon ou no Fediverso nós recomendamos ler <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>este artigo</a>.<br/><br/>Entre com o seu domínio abaixo (e.g. mastodon.social)",
"saved": "Evento salvo",
"recurrent": "Recorrente",
"ics": "ICS",
"recurrent_1m_days": "Dia {days} de cada mês",
"interact_with_me": "Siga-me",
"media_description": "Pode adicionar um cartaz (opcional)",
"same_day": "no mesmo dia",
"added": "Evento adicionado",
"what_description": "Título",
"description_description": "Descrição",
"tag_description": "Marcador",
"show_recurrent": "eventos recorrentes",
"anon": "Anônimo",
"anon_description": "Pode adicionar um evento sem se registar ou autenticar, mas precisa de esperar para alguém o ler,\ne confirmar que é um evento adequado. Não será possível modificá-lo depois disso.<br/><br/>\nPodem por vez <a href='/login'>autenticar-se</a> ou <a href='/register'>registar-se</a>. De qualquer modo, vá em frente e poderá obter uma resposta o mais rápido possível. ",
"added_anon": "Evento adicionado, mas ainda precisa ser confirmado.",
"updated": "Evento atualizado",
"where_description": "Onde está o evento? Se não está presente, então pode criá-lo.",
"confirmed": "Evento confirmado",
"not_found": "Não foi possível encontrar o evento",
"remove_confirmation": "Têm a certeza que quer remover este evento?",
"edit_recurrent": "Editar evento recorrente:",
"only_future": "apenas eventos futuros",
"recurrent_description": "Escolha a frequência e selecione os dias",
"multidate_description": "É um festival? Escolha quando ele começa e quando termina",
"multidate": "Mais dias",
"normal": "Normal",
"show_past": "também eventos anteriores",
"normal_description": "Escolha o dia.",
"recurrent_1w_days": "A cada {days}",
"each_week": "Toda semana",
"each_2w": "A cada duas semanas",
"each_month": "Todo mês",
"recurrent_2w_days": "{days} a cada dois",
"recurrent_2m_days": "Dia {days} a cada dois meses",
"recurrent_1m_ordinal": "A cada {n} {days} dias do mês",
"recurrent_2m_ordinal": "{n} {days} a cada dois meses",
"due": "até",
"from": "De",
"image_too_big": "A imagem não pode ser maior que 4MB",
"interact_with_me_at": "Interaja comigo no Fediverso atráves de",
"remove_recurrent_confirmation": "Têm a certeza que quer remover este evento recorrente?\nEventos passados serão mantidos, mas nenhum evento seguinte será criado.",
"import_URL": "Importar a partir de URL",
"import_ICS": "Importar a partir de ICS",
"import_description": "Pode importar eventos de outras plataformas e de outros domínios via formatos padrão (ICS e H-Event)",
"alt_text_description": "Descrição para pessoas com deficiências visuais",
"choose_focal_point": "Escolha o ponto focal",
"remove_media_confirmation": "Confirma a remoção da imagem?",
"download_flyer": "Baixar flyer",
"address_description": "Qual é o endereço?",
"address_description_osm": "Procure as coordenadas escrevendo o endereço. (contribuidores do <a href='http://osm.org/copyright'>OpenStreetMap</a>)",
"show_multidate": "Eventos com múltiplas datas",
"where_advanced_options": "Lugar — Opções avançadas",
"where_advanced_options_description": "Defina aqui propriedades do local adicionais",
"online_locations": "Localizações online",
"address_geocoded_disclaimer": "Se não conseguir encontrar o <strong>endereço da rua</strong> ou a <strong>porta da casa</strong> que procura nos resultados da geocodificação, pode inseri-los manualmente no campo “Endereço” sem perder as coordenadas. Considere também que o projeto <a target=\"_blank\" href=\"https://www.openstreetmap.org/\">OpenStreetMap</a> está aberto a contribuições. Se tiver Android, recomendamos o <a target=\"_blank\" href=\"https://f-droid.org/en/packages/de.westnordost.streetcomplete/\">StreetComplete</a>. ",
"online_locations_help": "Por exemplo, um link para uma sala de video-conferência e um link para outros recursos (máx. 3)",
"online_locations_fallback_urls": "Links de retorno"
},
"confirm": {
"not_valid": "Algo deu errado.",
"title": "Confirmação de usuário",
"valid": "A sua conta está confirmada, pode agora <a href=\"/login\">autenticar-se</a>"
},
"export": {
"intro": "Diferente de plataformas não sociais que fazem tudo para manter os utilizadores e os dados sobre eles, nós acreditamos que a informação, como pessoas, deve ser livre. Para isso deve atualizar-se sobre os eventos do seu interesse, sem necessariamente entrar nesta página.",
"insert_your_address": "Informe seu endereço de e-mail",
"feed_description": "Para seguir as atualizações de um computador ou telemóvel sem que precise de aceder a esta página periodicamente, utilize um leitor de feeds RSS. </p>\n\n<p> Com feeds RSS pode utilizar uma aplicação especial para receber atualizações de páginas que sejam do teu interesse. É uma boa maneira de seguir muitas páginas rapidamente, sem a necessidade de criar contas de utilizadores ou outras complicações. </p>\n\n<li> Se possui um Android, recomendamos <a href=\"https://f-droid.org/en/packages/net.frju.flym/\">Flym</a> ou Feeder </li>\n<li> Para iPhone / iPad pode utilizar <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8\"> Feed4U </a> </li>\n<li> Para computador fixo/ portátil nós recomendamos Feedbro, que pode ser instalado no <a href=\"https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/\"> Firefox </a> ou <a href=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa\"> Chrome </a>. </li>\n<br/>\nAdicionado este link ao seu leitor de RSS irá mantê-lo atualizado.",
"ical_description": "Computadores e smartphones normalmente possuem aplicações de calendário capazes de importar um calendário remoto.",
"list_description": "Se têm uma página e quer exibir uma lista de eventos, use o seguinte código",
"email_description": "Podes obter eventos que sejam do teu interesse via e-mail."
},
"oauth": {
"authorization_request": "A aplicação <code>{app}</code> solicita autorização em <code>{instance_name}</code>:",
"scopes": {
"event:write": "Adicionar e editar os seus eventos"
},
"redirected_to": "Depois da confirmação, será redirecionado para <code>{url}</code>"
},
"ordinal": {
"1": "primeiro",
"2": "segundo",
"3": "terceiro",
"4": "quarto",
"5": "quinto",
"-1": "último"
},
"settings": {
"remove_account": "Ao pressionar este botão a sua conta de utilizador será apagada. Eventos que publicou serão mantidos.",
"remove_account_confirm": "Está prestes a apagar a sua conta de utilizador permanentemente",
"update_confirm": "Quer salvar as suas alterações?",
"change_password": "Alterar sua senha",
"password_updated": "Senha alterada.",
"danger_section": "Seção perigosa"
},
"error": {
"email_taken": "Este e-mail já está em uso.",
"nick_taken": "Este nome de usuário já está em uso."
},
"setup": {
"https_warning": "Está a aceder por HTTP, lembre-se de alterar o valor de baseurl em config.json se mudar para HTTPS!",
"completed": "Configuração completa",
"start": "Iniciar",
"completed_description": "<p>Pode agora autenticar-se com o seguinte utilizador:<br/><br/>Utilizador: <b>{email}</b><br/>Palavra-passe: <b>{password}<b/></p>",
"copy_password_dialog": "Sim, precisa copiar a palavra-passe!"
},
"validators": {
"email": "Insira um e-mail válido",
"required": "{fieldName} é obrigatório",
"longitude": "Insira uma longitude válida (-180 < longitude < 180)",
"latitude": "Insira uma latitude válida (90 < latitude < 90)"
},
"about": "\n <p><a href='https://gancio.org'>Gancio</a> é uma agenda compartilhada para comunidades locais.</p>\n ",
"login": {
"not_registered": "Não registrado?",
"forgot_password": "Esqueceu sua senha?",
"insert_email": "Informe seu endereço de e-mail",
"ok": "Autenticado",
"description": "Ao autenticar-se poderá publicar novos eventos.",
"check_email": "Verifique sua caixa de entrada e de spam.",
"error": "Autenticação não realizada. Verifique suas informações de autenticação."
},
"recover": {
"not_valid_code": "Algo não funcionou corretamente."
},
"register": {
"error": "Erro: ",
"complete": "Registro precisa ser confirmado.",
"first_user": "Administrador criado",
"description": "Movimentos sociais devem se organizar e autofinanciar-se.<br/>\n<br/>Antes de poder publicar, <strong> a conta precisa ser aprovada por um administrador</strong>, considere que <strong> atrás deste site vai encontrar pessoas reais</strong>, então escreva duas linhas para nos informar que eventos teria interesse em publicar."
},
"auth": {
"fail": "Autenticação não efetuada. Têm a certeza que a sua palavra-passe está correta?",
"not_confirmed": "Não confirmado ainda…"
}
}

View file

@ -25,8 +25,8 @@
"hide": "Ocultar", "hide": "Ocultar",
"search": "Buscar", "search": "Buscar",
"info": "Info", "info": "Info",
"users": "Usuários", "users": "Utilizadores",
"share": "Compartilhar", "share": "Partilhar",
"name": "Nome", "name": "Nome",
"associate": "Associar", "associate": "Associar",
"logout": "Sair", "logout": "Sair",
@ -39,7 +39,7 @@
"copy": "Copiar", "copy": "Copiar",
"ok": "Ok", "ok": "Ok",
"cancel": "Cancelar", "cancel": "Cancelar",
"me": "Você", "me": "Tu",
"password_updated": "Senha alterada.", "password_updated": "Senha alterada.",
"resources": "Recursos", "resources": "Recursos",
"activate_user": "Confirmado", "activate_user": "Confirmado",
@ -97,60 +97,68 @@
"about": "Sobre", "about": "Sobre",
"content": "Conteúdo", "content": "Conteúdo",
"admin_actions": "Ações de admin", "admin_actions": "Ações de admin",
"recurring_event_actions": "Ações de eventos recorrentes" "recurring_event_actions": "Ações de eventos recorrentes",
"tag": "Etiqueta",
"latitude": "Latitude",
"longitude": "Longitude",
"search_coordinates": "Procurar coordenadas",
"online": "On-line",
"test": "Teste",
"show_preview": "Mostrar pré-visualização",
"clone": "Clone"
}, },
"admin": { "admin": {
"user_block_confirm": "Você está certo que quer bloquear o usuário {user}?", "user_block_confirm": "Têm a certeza que quer bloquear o utilizador {user}?",
"filter_instances": "Filtrar instâncias", "filter_instances": "Filtrar domínios",
"user_add_help": "Um e-mail com instruções para confirmar a inscrição e escolher uma senha será enviada ao novo usuário", "user_add_help": "Um e-mail com instruções para confirmar a inscrição e escolher uma senha será enviada ao novo usuário",
"show_resource": "Mostrar recurso", "show_resource": "Mostrar recurso",
"block_user": "Bloquear usuário", "block_user": "Bloquear utilizador",
"filter_users": "Filtrar usuários", "filter_users": "Filtrar utilizadores",
"hide_resource": "Ocultar recurso", "hide_resource": "Ocultar recurso",
"delete_resource": "Remover recurso", "delete_resource": "Remover recurso",
"delete_resource_confirm": "Você está certo que quer remover este recurso?", "delete_resource_confirm": "Têm a certeza que quer remover este recurso?",
"show_smtp_setup": "Configurações de e-mail", "show_smtp_setup": "Configurações de e-mail",
"resources": "Recursos", "resources": "Recursos",
"delete_announcement_confirm": "Você está certo que quer remover o anúncio?", "delete_announcement_confirm": "Têm a certeza que quer remover o anúncio?",
"smtp_hostname": "Hostname SMTP", "smtp_hostname": "Hostname do SMTP",
"collections_description": "Coleções são agrupamentos de eventos por marcadores e locais. Eles serão exibidos na página principal", "collections_description": "Coleções são agrupamentos de eventos por marcadores e locais. Eles serão exibidos na página principal",
"new_collection": "Nova coleção", "new_collection": "Nova coleção",
"disable_admin_user_confirm": "Você está certo que quer remover permissões de administração de {user}?", "disable_admin_user_confirm": "Têm a certeza que quer remover permissões de administração de {user}?",
"enable_admin_user_confirm": "Você está certo que quer adicionar permissões de administrador para {user}?", "enable_admin_user_confirm": "Têm a certeza que quer adicionar permissões de administrador para {user}?",
"event_remove_ok": "Evento removido", "event_remove_ok": "Evento removido",
"smtp_description": "<ul><li>Administrador deve receber um e-mail quando um evento anônimo for adicionado (se habilitado).</li><li>Administrador deve receber um e-mail de requisição de registro (se habilitado).</li><li>Usuário deve receber um e-mail de solicitação de registro.</li><li>Usuário deve receber um e-mail de confirmação de registro.</li><li>Usuário deve recever um e-mail de confirmação quando registrado diretamente por um administrador.</li><li>Usuários devem receber um e-mail para recuperar a senha quando eles esquecerem ela</li></ul>", "smtp_description": "<ul><li>Administrador deve receber um e-mail quando um evento anónimo for adicionado (se habilitado).</li><li>Administrador deve receber um e-mail de requisição de registo (se habilitado).</li><li>Utilizador deve receber um e-mail de solicitação de registro.</li><li>Utilizador deve receber um e-mail de confirmação de registo.</li><li>Utilizador deve receber um e-mail de confirmação quando registado diretamente por um administrador.</li><li>Utilizadores devem receber um e-mail para recuperar a senha quando eles esquecerem ela</li></ul>",
"allow_registration_description": "Permitir registro aberto de usuários?", "allow_registration_description": "Permitir registo aberto de utilizadores?",
"block": "Bloquear", "block": "Bloquear",
"unblock": "Desbloquear", "unblock": "Desbloquear",
"instance_name": "Nome da instância", "instance_name": "Nome da instância",
"favicon": "Logo", "favicon": "Logo",
"instance_block_confirm": "Você está certo que quer bloquear a instância {instance}?", "instance_block_confirm": "Têm a certeza que quer bloquear o domínio {instance}?",
"enable_federation": "Habilitar federação", "enable_federation": "Habilitar federação",
"enable_federation_help": "Será possível seguir está instância a partir do Fediverso", "enable_federation_help": "Será possível seguir está instância a partir do Fediverso",
"add_instance": "Adicionar instância", "add_instance": "Adicionar instância",
"hide_boost_bookmark_help": "Ocultar os pequenos ícones mostrando o número de impulsos e favoritos vindos do Fediverso", "hide_boost_bookmark_help": "Ocultar os pequenos ícones mostrando o número de impulsos e favoritos vindos do Fediverso",
"announcement_remove_ok": "Anúncio removido", "announcement_remove_ok": "Anúncio removido",
"instance_timezone_description": "Gancio é desenvolvido para coletar os eventos de um local específico, como uma cidade. Todos os eventos nesse local serão exibidos no fuso-horário escolhido para ele.", "instance_timezone_description": "Gancio é desenvolvido para coletar os eventos de um local específico, como uma cidade. Todos os eventos nesse local serão exibidos no fuso-horário escolhido para ele.",
"instance_locale_description": "Idioma de preferência para as páginas. Algumas vezes as mensagens precisam ser exibidas em um mesmo idioma para todos (por exemplo quando publicando através do ActivityPub ou quando enviar alguns e-mails). Nestes casos o idioma seleciona abaixo será o utilizado.", "instance_locale_description": "Idioma de preferência para as páginas. Algumas vezes as mensagens precisam ser exibidas em um mesmo idioma para todos (por exemplo, quando publicando através do ActivityPub ou quando enviar alguns e-mails). Nestes casos o idioma seleciona abaixo será o utilizado.",
"title_description": "É utilizado no título da página, no assunto do e-mail para exportar feeds RSS e ICS.", "title_description": "É utilizado no título da página, no assunto do e-mail para exportar feeds RSS e ICS.",
"instance_name_help": "Conta ActivityPub para seguir", "instance_name_help": "Conta ActivityPub para seguir",
"enable_trusted_instances": "Habilitar instâncias amigáveis", "enable_trusted_instances": "Habilitar domínios amigáveis",
"trusted_instances_help": "A lista de instâncias amigáveis que serão exibidas no cabeçalho", "trusted_instances_help": "A lista de domínios amigáveis será exibido no cabeçalho",
"trusted_instances_label": "Etiqueta de navegação para instâncias amigas", "trusted_instances_label": "Etiqueta de navegação para domínios amigos",
"trusted_instances_label_default": "Instâncias amigas", "trusted_instances_label_default": "Domínios amigos",
"trusted_instances_label_help": "A etiqueta padrão é 'Instâncias amigas'", "trusted_instances_label_help": "A etiqueta padrão é 'Domínios amigos'",
"add_trusted_instance": "Adicione uma instância amigável", "add_trusted_instance": "Adicione um domínio amigável",
"footer_links": "Links de rodapé", "footer_links": "Links de rodapé",
"delete_footer_link_confirm": "Está certo que quer remover este link?", "delete_footer_link_confirm": "Têm a certeza que quer remover este link?",
"edit_place": "Editar local", "edit_place": "Editar local",
"smtp_port": "Porta SMTP", "smtp_port": "Porta do SMTP",
"smtp_secure": "SMTP Seguro (TLS ou STARTTLS)", "smtp_secure": "SMTP Seguro (TLS ou STARTTLS)",
"smtp_use_sendmail": "Utilizar sendmail", "smtp_use_sendmail": "Utilizar sendmail",
"instance_place_help": "A etiqueta para exibir em outras instâncias", "instance_place_help": "A etiqueta para exibir em outros domínios",
"delete_trusted_instance_confirm": "Você quer realmente remover este item do menu de instâncias amigas?", "delete_trusted_instance_confirm": "Quer realmente remover este item do menu de domínios amigos?",
"sender_email": "E-mail do remetente", "sender_email": "E-mail do remetente",
"widget": "Widget", "widget": "Widget",
"wrong_domain_warning": "A baseurl configurado em config.json <b>({baseurl})</b> é diferente da que você está visitando <b>({url})</b>", "wrong_domain_warning": "O baseurl configurado no config.json <b>({baseurl})</b> é diferente do que está a usar para visitar <b>({url})</b>",
"edit_collection": "Editar Coleção", "edit_collection": "Editar Coleção",
"enable_resources_help": "Permitir adicionar recursos para o evento a partir do Fediverso", "enable_resources_help": "Permitir adicionar recursos para o evento a partir do Fediverso",
"hide_boost_bookmark": "Ocultar impulsos/favoritos", "hide_boost_bookmark": "Ocultar impulsos/favoritos",
@ -159,19 +167,19 @@
"enable_resources": "Habilitar recursos", "enable_resources": "Habilitar recursos",
"delete_user": "Remover", "delete_user": "Remover",
"remove_admin": "Remover administrador", "remove_admin": "Remover administrador",
"place_description": "Se você colocou o local ou o endereço errado, você pode alterá-lo.<br/>Todos os eventos atuais e passados associados com esse local terão o endereço alterado.", "place_description": "Se colocou o local ou o endereço errado, pode alterá-lo.<br/>Todos os eventos atuais e passados associados com este local terão o endereço alterado.",
"event_confirm_description": "Você pode confirmar eventos criados por usuários anônimos aqui", "event_confirm_description": "Pode confirmar eventos criados por utilizadores anónimos aqui",
"disable_user_confirm": "Você está certo que quer desabilitar {user}?", "disable_user_confirm": "Têm a certeza que quer desativar {user}?",
"delete_user_confirm": "Você está certo que quer remover {user}?", "delete_user_confirm": "Têm a certeza que quer remover {user}?",
"user_remove_ok": "Usuário removido", "user_remove_ok": "Usuário removido",
"user_create_ok": "Usuário criado", "user_create_ok": "Usuário criado",
"allow_anon_event": "Permitir eventos anônimos (precisam ser confirmados)?", "allow_anon_event": "Permitir eventos anônimos (precisam ser confirmados)?",
"allow_recurrent_event": "Permitir eventos recorrentes", "allow_recurrent_event": "Permitir eventos recorrentes",
"recurrent_event_visible": "Exibir eventos recorrentes por padrão", "recurrent_event_visible": "Exibir eventos recorrentes por padrão",
"user_blocked": "Usuário {user} bloqueado", "user_blocked": "Utilizador {user} bloqueado",
"announcement_description": "Nesta seção você pode inserir anúncios que serão exibidos na página principal", "announcement_description": "Nesta secção pode inserir anúncios que serão exibidos na página principal",
"description_description": "Exibido no cabeçalho próximo ao título", "description_description": "Exibido no cabeçalho próximo ao título",
"instance_place": "Local indicativo desta instância", "instance_place": "Local indicativo deste domínio",
"is_dark": "Tema escuro", "is_dark": "Tema escuro",
"add_link": "Adicionar link", "add_link": "Adicionar link",
"new_announcement": "Novo anúncio", "new_announcement": "Novo anúncio",
@ -179,29 +187,44 @@
"smtp_test_success": "Um e-mail de teste foi enviado para {admin_email}, por favor verifique sua caixa de entrada", "smtp_test_success": "Um e-mail de teste foi enviado para {admin_email}, por favor verifique sua caixa de entrada",
"smtp_test_button": "Enviar e-mail de teste", "smtp_test_button": "Enviar e-mail de teste",
"allow_geolocation": "Permitir geolocalização de eventos", "allow_geolocation": "Permitir geolocalização de eventos",
"config_plugin": "Configuração de plugin", "config_plugin": "Configuração da extensão",
"fallback_image": "Imagem alternativa", "fallback_image": "Imagem alternativa",
"header_image": "Imagem de cabeçalho", "header_image": "Imagem de cabeçalho",
"hide_thumbs": "Ocultar miniaturas", "hide_thumbs": "Ocultar miniaturas",
"default_images_help": "Você precisa <a href='/admin?tab=theme'>recarregar</a> a página para ver as mudanças.", "default_images_help": "Precisa de <a href='/admin?tab=theme'>recarregar</a> a página para ver as mudanças.",
"domain": "Domínio", "domain": "Domínio",
"default_images": "Imagens padrão", "default_images": "Imagens padrão",
"known_users": "Usuários conhecidos", "known_users": "Utilizadores conhecidos",
"created_at": "Criado em", "created_at": "Criado em",
"hide_calendar": "Ocultar calendário", "hide_calendar": "Ocultar calendário",
"blocked": "Bloqueado", "blocked": "Bloqueado",
"admin_email": "E-mail do admin", "admin_email": "E-mail do admin",
"tilelayer_provider_attribution": "Atribuição", "tilelayer_provider_attribution": "Atribuição",
"geolocation": "Geolocalização" "geolocation": "Geolocalização",
"edit_tag": "Editar etiqueta",
"allow_online_event": "Permitir eventos online",
"allow_online_event_hint": "Pedir por links ",
"admin_email_help": "O e-mail que utilizaremos como remetente para enviar mensagens. Este é também o endereço para o qual são enviadas as mensagens da administração",
"allow_multidate_event": "Permitir eventos com múltiplas datas",
"delete_tag_confirm": "Tem certeza que quer remover a etiqueta \"{tag}\"? A etiqueta será removida de {n} eventos.",
"delete_collection_confirm": "Têm a certeza que quer remover a coleção <u>{collection}</u>?",
"colors": "Cores",
"geocoding_provider_help": "O provedor padrão é o Nominatim",
"geocoding_provider_type_help": "O software padrão é o Nominatim",
"geocoding_countrycodes": "Código de países",
"geocoding_provider_type": "Software de geocodificação",
"geocoding_provider": "Provedor de geocodificação",
"tilelayer_provider_help": "O provedor padrão é o OpenStreetMap",
"edit_tag_help": "Você pode alterar o marcador ao substituí-lo por um novo ou mesclando-o com um já existente. Os {n} eventos associados também serão alterados."
}, },
"event": { "event": {
"follow_me_description": "Uma das maneiras de se manter atualizado com os eventos publicados aqui em {title},\né seguir a conta <u>{account}</u> no Fediverso, por exemplo via Mastodon, e possivelmente adicionar recursos para um evento a partir de lá.<br/><br/>\nSe você nunca ouviu falar sobre Mastodon ou do Fediverso nós recomendamos ler <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>este artigo</a>.<br/><br/>Entre com sua instância abaixo (e.g. mastodon.social)", "follow_me_description": "Uma das maneiras de se manter atualizado com os eventos publicados aqui em {title},\né seguir a conta <u>{account}</u> no Fediverso, por exemplo, via Mastodon, e possivelmente adicionar recursos para um evento a partir de lá.<br/><br/>\nSe nunca ouviu falar sobre Mastodon ou no Fediverso nós recomendamos ler <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>este artigo</a>.<br/><br/>Entre com o seu domínio abaixo (e.g. mastodon.social)",
"saved": "Evento salvo", "saved": "Evento salvo",
"recurrent": "Recorrente", "recurrent": "Recorrente",
"ics": "ICS", "ics": "ICS",
"recurrent_1m_days": "Dia {days} de cada mês", "recurrent_1m_days": "Dia {days} de cada mês",
"interact_with_me": "Siga-me", "interact_with_me": "Siga-me",
"media_description": "Você pode adicionar um flyer (opcional)", "media_description": "Pode adicionar um cartaz (opcional)",
"same_day": "no mesmo dia", "same_day": "no mesmo dia",
"added": "Evento adicionado", "added": "Evento adicionado",
"what_description": "Título", "what_description": "Título",
@ -209,13 +232,13 @@
"tag_description": "Marcador", "tag_description": "Marcador",
"show_recurrent": "eventos recorrentes", "show_recurrent": "eventos recorrentes",
"anon": "Anônimo", "anon": "Anônimo",
"anon_description": "Você pode adicionar um evento sem se registrar ou autenticar-se, mas você precisa esperar alguém para ler,\nconfirmar que é um evento adequado. Não será possível modifiá-lo.<br/><br/>\nVocê pode ao invés <a href='/login'>autenticar-se</a> ou <a href='/register'>registrar-se</a>. De qualquer modo, vá em frente e consiga uma resposta o mais rápido possível. ", "anon_description": "Pode adicionar um evento sem se registar ou autenticar, mas precisa de esperar para alguém o ler,\ne confirmar que é um evento adequado. Não será possível modificá-lo depois disso.<br/><br/>\nPodem por vez <a href='/login'>autenticar-se</a> ou <a href='/register'>registar-se</a>. De qualquer modo, vá em frente e poderá obter uma resposta o mais rápido possível. ",
"added_anon": "Evento adicionado, mas ainda precisa ser confirmado.", "added_anon": "Evento adicionado, mas ainda precisa ser confirmado.",
"updated": "Evento atualizado", "updated": "Evento atualizado",
"where_description": "Onde está o evento? Se não está visível você pode criá-lo.", "where_description": "Onde está o evento? Se não está presente, então pode criá-lo.",
"confirmed": "Evento confirmado", "confirmed": "Evento confirmado",
"not_found": "Não foi possível encontrar o evento", "not_found": "Não foi possível encontrar o evento",
"remove_confirmation": "Você está certo que quer remover este evento?", "remove_confirmation": "Têm a certeza que quer remover este evento?",
"edit_recurrent": "Editar evento recorrente:", "edit_recurrent": "Editar evento recorrente:",
"only_future": "apenas eventos futuros", "only_future": "apenas eventos futuros",
"recurrent_description": "Escolha a frequência e selecione os dias", "recurrent_description": "Escolha a frequência e selecione os dias",
@ -230,55 +253,62 @@
"each_month": "Todo mês", "each_month": "Todo mês",
"recurrent_2w_days": "{days} a cada dois", "recurrent_2w_days": "{days} a cada dois",
"recurrent_2m_days": "Dia {days} a cada dois meses", "recurrent_2m_days": "Dia {days} a cada dois meses",
"recurrent_1m_ordinal": "{n} {days} de cada mês", "recurrent_1m_ordinal": "A cada {n} {days} dias do mês",
"recurrent_2m_ordinal": "{n} {days} a cada dois meses", "recurrent_2m_ordinal": "{n} {days} a cada dois meses",
"due": "até", "due": "até",
"from": "De", "from": "De",
"image_too_big": "A imagem não pode ser maior que 4MB", "image_too_big": "A imagem não pode ser maior que 4MB",
"interact_with_me_at": "Interaja comigo no Fediverso atráves de", "interact_with_me_at": "Interaja comigo no Fediverso atráves de",
"remove_recurrent_confirmation": "Você está certo que quer remover este evento recorrente?\nEventos passados serão mantidos, mas nenhum evento seguinte será criado.", "remove_recurrent_confirmation": "Têm a certeza que quer remover este evento recorrente?\nEventos passados serão mantidos, mas nenhum evento seguinte será criado.",
"import_URL": "Importar a partir de URL", "import_URL": "Importar a partir de URL",
"import_ICS": "Importar a partir de ICS", "import_ICS": "Importar a partir de ICS",
"import_description": "Você pode importar eventos de outras plataformas e outras instâncias através de formatos padrão (ics e h-event)", "import_description": "Pode importar eventos de outras plataformas e de outros domínios via formatos padrão (ICS e H-Event)",
"alt_text_description": "Descrição para pessoas com deficiências visuais", "alt_text_description": "Descrição para pessoas com deficiências visuais",
"choose_focal_point": "Escolha o ponto focal", "choose_focal_point": "Escolha o ponto focal",
"remove_media_confirmation": "Você confirma a remoção da imagem?", "remove_media_confirmation": "Confirma a remoção da imagem?",
"download_flyer": "Baixar flyer", "download_flyer": "Baixar flyer",
"address_description": "Qual é o endereço?", "address_description": "Qual é o endereço?",
"address_description_osm": "Qual é o endereço? (contribuidores do <a href='http://osm.org/copyright'>OpenStreetMap</a>)" "address_description_osm": "Procure as coordenadas escrevendo o endereço. (contribuidores do <a href='http://osm.org/copyright'>OpenStreetMap</a>)",
"show_multidate": "Eventos com múltiplas datas",
"where_advanced_options": "Lugar — Opções avançadas",
"where_advanced_options_description": "Defina aqui propriedades do local adicionais",
"online_locations": "Localizações online",
"address_geocoded_disclaimer": "Se não conseguir encontrar o <strong>endereço da rua</strong> ou a <strong>porta da casa</strong> que procura nos resultados da geocodificação, pode inseri-los manualmente no campo “Endereço” sem perder as coordenadas. Considere também que o projeto <a target=\"_blank\" href=\"https://www.openstreetmap.org/\">OpenStreetMap</a> está aberto a contribuições. Se tiver Android, recomendamos o <a target=\"_blank\" href=\"https://f-droid.org/en/packages/de.westnordost.streetcomplete/\">StreetComplete</a>. ",
"online_locations_help": "Por exemplo, um link para uma sala de video-conferência e um link para outros recursos (máx. 3)",
"online_locations_fallback_urls": "Links de retorno"
}, },
"confirm": { "confirm": {
"not_valid": "Algo deu errado.", "not_valid": "Algo deu errado.",
"title": "Confirmação de usuário", "title": "Confirmação de usuário",
"valid": "Sua conta está confirmada, você pode agora <a href=\"/login\">autenticar-se</a>" "valid": "A sua conta está confirmada, pode agora <a href=\"/login\">autenticar-se</a>"
}, },
"export": { "export": {
"intro": "Diferente de plataformas não-sociais que fazem tudo para manter os usuários e os dados sobre eles, nós acreditamos que a informação, como pessoas, deve ser livre. Para isso você se atualizar sobre os eventos de seu interesse, sem necessariamente entrar nesta página.", "intro": "Diferente de plataformas não sociais que fazem tudo para manter os utilizadores e os dados sobre eles, nós acreditamos que a informação, como pessoas, deve ser livre. Para isso deve atualizar-se sobre os eventos do seu interesse, sem necessariamente entrar nesta página.",
"insert_your_address": "Informe seu endereço de e-mail", "insert_your_address": "Informe seu endereço de e-mail",
"feed_description": "Para seguir as atualizações de um computador ou smartphone sem que você precise acessar essa página periodicamente, utilize um feeds RSS. </p>\n\n<p> Com feeds RSS você pode utilizar um app especial para receber atualizações de páginas que te interessam. É uma boa maneira de seguir muitas páginas rapidamente, sem a necessidade de criar contas de usuários ou outras complicações. </p>\n\n<li> Se você possui um Android, recomendamos <a href=\"https://f-droid.org/en/packages/net.frju.flym/\">Flym</a> ou Feeder </li>\n<li> Para iPhone / iPad você pode utilizar <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8\"> Feed4U </a> </li>\n<li> Para desktop / laptop nós recomendamos Feedbro, que pode ser instalado no <a href=\"https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/\"> Firefox </a> ou <a href=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa\"> Chrome </a>. </li>\n<br/>\nAdicionado este link ao seu leitor de RSS irá mantê-lo atualizado.", "feed_description": "Para seguir as atualizações de um computador ou telemóvel sem que precise de aceder a esta página periodicamente, utilize um leitor de feeds RSS. </p>\n\n<p> Com feeds RSS pode utilizar uma aplicação especial para receber atualizações de páginas que sejam do teu interesse. É uma boa maneira de seguir muitas páginas rapidamente, sem a necessidade de criar contas de utilizadores ou outras complicações. </p>\n\n<li> Se possui um Android, recomendamos <a href=\"https://f-droid.org/en/packages/net.frju.flym/\">Flym</a> ou Feeder </li>\n<li> Para iPhone / iPad pode utilizar <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8\"> Feed4U </a> </li>\n<li> Para computador fixo/ portátil nós recomendamos Feedbro, que pode ser instalado no <a href=\"https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/\"> Firefox </a> ou <a href=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa\"> Chrome </a>. </li>\n<br/>\nAdicionado este link ao seu leitor de RSS irá mantê-lo atualizado.",
"ical_description": "Computadores e smartphones normalmente possuem aplicações de calendário capazes de importar um calendário remoto.", "ical_description": "Computadores e smartphones normalmente possuem aplicações de calendário capazes de importar um calendário remoto.",
"list_description": "Se você tem uma página e quer exibir uma lista de eventos, use o seguinte código", "list_description": "Se m uma página e quer exibir uma lista de eventos, use o seguinte código",
"email_description": "Você pode obter os eventos que te interessam através de e-mail." "email_description": "Podes obter eventos que sejam do teu interesse via e-mail."
}, },
"oauth": { "oauth": {
"authorization_request": "A aplicação <code>{app}</code> solicita autorização em <code>{instance_name}</code>:", "authorization_request": "A aplicação <code>{app}</code> solicita autorização em <code>{instance_name}</code>:",
"scopes": { "scopes": {
"event:write": "Adicionar e editar os seus eventos" "event:write": "Adicionar e editar os seus eventos"
}, },
"redirected_to": "Depois da confirmação, você será redirecionado para <code>{url}</code>" "redirected_to": "Depois da confirmação, será redirecionado para <code>{url}</code>"
}, },
"ordinal": { "ordinal": {
"2": "segundo",
"1": "primeiro", "1": "primeiro",
"5": "quinto", "2": "segundo",
"-1": "último",
"3": "terceiro", "3": "terceiro",
"4": "quarto" "4": "quarto",
"5": "quinto",
"-1": "último"
}, },
"settings": { "settings": {
"remove_account": "Ao pressionar este botão sua conta de usuário será removida. Eventos que você publicou serão mantidos.", "remove_account": "Ao pressionar este botão a sua conta de utilizador será apagada. Eventos que publicou serão mantidos.",
"remove_account_confirm": "Você está prestes a remover sua conta de usuário permanentemente", "remove_account_confirm": "Está prestes a apagar a sua conta de utilizador permanentemente",
"update_confirm": "Você quer salvar sua modificação?", "update_confirm": "Quer salvar as suas alterações?",
"change_password": "Alterar sua senha", "change_password": "Alterar sua senha",
"password_updated": "Senha alterada.", "password_updated": "Senha alterada.",
"danger_section": "Seção perigosa" "danger_section": "Seção perigosa"
@ -288,15 +318,17 @@
"nick_taken": "Este nome de usuário já está em uso." "nick_taken": "Este nome de usuário já está em uso."
}, },
"setup": { "setup": {
"https_warning": "Você está acessando por HTTP, lembre-se de alterar o valor de baseurl em config.json se você mudar para HTTPS!", "https_warning": "Está a aceder por HTTP, lembre-se de alterar o valor de baseurl em config.json se mudar para HTTPS!",
"completed": "Configuração completa", "completed": "Configuração completa",
"start": "Iniciar", "start": "Iniciar",
"completed_description": "<p>Você pode agora autenticar-se com o seguinte usuário:<br/><br/>Usuário: <b>{email}</b><br/>Senha: <b>{password}<b/></p>", "completed_description": "<p>Pode agora autenticar-se com o seguinte utilizador:<br/><br/>Utilizador: <b>{email}</b><br/>Palavra-passe: <b>{password}<b/></p>",
"copy_password_dialog": "Sim, você precisa copiar a senha!" "copy_password_dialog": "Sim, precisa copiar a palavra-passe!"
}, },
"validators": { "validators": {
"email": "Insira um e-mail válido", "email": "Insira um e-mail válido",
"required": "{fieldName} é obrigatório" "required": "{fieldName} é obrigatório",
"longitude": "Insira uma longitude válida (-180 < longitude < 180)",
"latitude": "Insira uma latitude válida (90 < latitude < 90)"
}, },
"about": "\n <p><a href='https://gancio.org'>Gancio</a> é uma agenda compartilhada para comunidades locais.</p>\n ", "about": "\n <p><a href='https://gancio.org'>Gancio</a> é uma agenda compartilhada para comunidades locais.</p>\n ",
"login": { "login": {
@ -304,7 +336,7 @@
"forgot_password": "Esqueceu sua senha?", "forgot_password": "Esqueceu sua senha?",
"insert_email": "Informe seu endereço de e-mail", "insert_email": "Informe seu endereço de e-mail",
"ok": "Autenticado", "ok": "Autenticado",
"description": "Ao autenticar-se você pode publicar novos eventos.", "description": "Ao autenticar-se pode publicar novos eventos.",
"check_email": "Verifique sua caixa de entrada e de spam.", "check_email": "Verifique sua caixa de entrada e de spam.",
"error": "Autenticação não realizada. Verifique suas informações de autenticação." "error": "Autenticação não realizada. Verifique suas informações de autenticação."
}, },
@ -315,10 +347,10 @@
"error": "Erro: ", "error": "Erro: ",
"complete": "Registro precisa ser confirmado.", "complete": "Registro precisa ser confirmado.",
"first_user": "Administrador criado", "first_user": "Administrador criado",
"description": "Movimentos sociais devem se organizar e se auto financiar.<br/>\n<br/>Antes de poder publicar, <strong> a conta precisa ser aprovada</strong>, considere que <strong> atrás deste site você vai encontrar pessoas reais</strong>, então escreva duas linhas para nos informar que eventos você gostaria de publicar." "description": "Movimentos sociais devem se organizar e autofinanciar-se.<br/>\n<br/>Antes de poder publicar, <strong> a conta precisa ser aprovada por um administrador</strong>, considere que <strong> atrás deste site vai encontrar pessoas reais</strong>, então escreva duas linhas para nos informar que eventos teria interesse em publicar."
}, },
"auth": { "auth": {
"fail": "Autenticação não efetuada. Você está certo que sua senha está correta?", "fail": "Autenticação não efetuada. Têm a certeza que a sua palavra-passe está correta?",
"not_confirmed": "Não confirmado ainda…" "not_confirmed": "Não confirmado ainda…"
} }
} }

1
locales/pt_PT.json Normal file
View file

@ -0,0 +1 @@
{}

View file

@ -96,7 +96,8 @@
"tag": "Тег", "tag": "Тег",
"calendar": "Календарь", "calendar": "Календарь",
"next": "След.", "next": "След.",
"export": "Экспорт" "export": "Экспорт",
"clone": "Клон"
}, },
"login": { "login": {
"description": "Войдя в систему, вы можете публиковать новые события.", "description": "Войдя в систему, вы можете публиковать новые события.",

View file

@ -88,7 +88,8 @@
"copied": "Skopírované", "copied": "Skopírované",
"embed": "Vložiť", "embed": "Vložiť",
"instances": "Inštancie", "instances": "Inštancie",
"embed_title": "Vložiť toto podujatie na tvoju web stránku" "embed_title": "Vložiť toto podujatie na tvoju web stránku",
"clone": "Klonovať"
}, },
"login": { "login": {
"description": "Po prihlásení sa môžete publikovat nové podujatia.", "description": "Po prihlásení sa môžete publikovat nové podujatia.",

View file

@ -88,7 +88,8 @@
"close": "关闭", "close": "关闭",
"disable": "禁用", "disable": "禁用",
"password_updated": "密码已修改。", "password_updated": "密码已修改。",
"reset": "重置" "reset": "重置",
"clone": "克隆"
}, },
"export": { "export": {
"list_description": "如果你有一个网站并希望展示一个事件列表,使用以下代码", "list_description": "如果你有一个网站并希望展示一个事件列表,使用以下代码",
@ -264,12 +265,12 @@
"valid": "你的账户已被确认,你现在可以 <a href=\"/login\">登录</a>" "valid": "你的账户已被确认,你现在可以 <a href=\"/login\">登录</a>"
}, },
"ordinal": { "ordinal": {
"1": "第一",
"2": "第二",
"3": "第三",
"4": "第四", "4": "第四",
"5": "第五", "5": "第五",
"2": "第二", "-1": "最后"
"-1": "最后",
"1": "第一",
"3": "第三"
}, },
"validators": { "validators": {
"required": "{fieldName} 是必填项", "required": "{fieldName} 是必填项",

View file

@ -1,6 +1,9 @@
const config = require('./server/config.js') const config = require('./server/config.js')
const locales = require('./locales/index') const locales = require('./locales/index')
import { ca, de, en, es, eu, fr, gl, it, nb, nl, pl, pt, sk, ru, zhHans } from 'vuetify/es5/locale' import { ca, cs, de, en, es, eu, fr, gl, it, nb, nl, pl, pt, sk, ru, zhHans } from 'vuetify/es5/locale'
const dns = require('node:dns')
dns.setDefaultResultOrder('ipv4first')
const isDev = (process.env.NODE_ENV !== 'production') const isDev = (process.env.NODE_ENV !== 'production')
module.exports = { module.exports = {
@ -141,7 +144,7 @@ module.exports = {
}, },
buildModules: ['@nuxtjs/vuetify'], buildModules: ['@nuxtjs/vuetify'],
vuetify: { vuetify: {
lang: { locales: { ca, de, en, es, eu, fr, gl, it, nb, nl, pl, pt, sk, ru, zhHans } }, lang: { locales: { ca, cs, de, en, es, eu, fr, gl, it, nb, nl, pl, pt, sk, ru, zhHans } },
treeShake: true, treeShake: true,
defaultAssets: false, defaultAssets: false,
optionsPath: './vuetify.options.js' }, optionsPath: './vuetify.options.js' },

View file

@ -1,6 +1,6 @@
{ {
"name": "gancio", "name": "gancio",
"version": "1.6.14-beta", "version": "1.6.19",
"description": "A shared agenda for local communities", "description": "A shared agenda for local communities",
"author": "lesion", "author": "lesion",
"scripts": { "scripts": {
@ -33,46 +33,45 @@
"yarn.lock" "yarn.lock"
], ],
"engines": { "engines": {
"node": ">=15 <=16" "node": ">=14 <=18"
}, },
"dependencies": { "dependencies": {
"@mdi/js": "^7.1.96", "@mdi/js": "^7.3.67",
"@nuxtjs/auth": "^4.9.1", "@nuxtjs/auth": "^4.9.1",
"@nuxtjs/axios": "^5.13.5", "@nuxtjs/axios": "^5.13.5",
"@nuxtjs/i18n": "^7.3.0", "@nuxtjs/i18n": "^7.3.0",
"@nuxtjs/sitemap": "^2.4.0", "@nuxtjs/sitemap": "^2.4.0",
"accept-language": "^3.0.18", "accept-language": "^3.0.18",
"axios": "^0.27.2",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"body-parser": "^1.20.2", "body-parser": "^1.20.2",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"cookie-session": "^2.0.0", "cookie-session": "^2.0.0",
"cookie-universal-nuxt": "^2.2.2", "cookie-universal-nuxt": "^2.2.2",
"cors": "^2.8.5", "cors": "^2.8.5",
"dayjs": "^1.11.8", "dayjs": "^1.11.10",
"dompurify": "^3.0.3", "dompurify": "^3.0.6",
"email-templates": "^10.0.1", "email-templates": "^11.1.1",
"express": "^4.18.1", "express": "^4.18.1",
"express-rate-limit": "^6.7.0", "express-rate-limit": "^7.1.1",
"http-signature": "^1.3.6", "http-signature": "^1.3.6",
"https-proxy-agent": "^5.0.1", "https-proxy-agent": "^7.0.2",
"ical.js": "^1.5.0", "ical.js": "^1.5.0",
"ics": "^3.1.0", "ics": "^3.5.0",
"jsdom": "^21.1.0", "jsdom": "^22.1.0",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"linkify-html": "^4.1.1", "linkify-html": "^4.1.1",
"linkifyjs": "4.1.1", "linkifyjs": "4.1.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"luxon": "^3.3.0", "luxon": "^3.4.3",
"mariadb": "^2.5.6", "mariadb": "^3.2.2",
"memory-cache": "^0.2.0", "memory-cache": "^0.2.0",
"microformat-node": "^2.0.1", "microformat-node": "^2.0.1",
"minify-css-string": "^1.0.0", "minify-css-string": "^1.0.0",
"mkdirp": "^2.1.6", "mkdirp": "^3.0.1",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"mysql2": "^2.3.3", "mysql2": "^2.3.3",
"nuxt-edge": "2.17.0-28098741.f3c5f95", "nuxt-edge": "2.17.2-28258581.6132947",
"oauth2orize": "^1.11.1", "oauth2orize": "^1.12.0",
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-anonymous": "^1.0.1", "passport-anonymous": "^1.0.1",
"passport-custom": "^1.1.1", "passport-custom": "^1.1.1",
@ -80,32 +79,33 @@
"passport-http-bearer": "^1.0.1", "passport-http-bearer": "^1.0.1",
"passport-oauth2-client-password": "^0.1.2", "passport-oauth2-client-password": "^0.1.2",
"passport-oauth2-client-public": "^0.0.1", "passport-oauth2-client-public": "^0.0.1",
"pg": "^8.11.0", "pg": "^8.11.3",
"sequelize": "^6.32.0", "semver": "^7.5.4",
"sequelize": "^6.33.0",
"sequelize-slugify": "^1.6.2", "sequelize-slugify": "^1.6.2",
"sharp": "^0.27.2", "sharp": "^0.27.2",
"sqlite3": "^5.1.4", "sqlite3": "^5.1.4",
"telegraf": "^4.12.2", "telegraf": "^4.14.0",
"tiptap": "^1.32.0", "tiptap": "^1.32.0",
"tiptap-extensions": "^1.35.0", "tiptap-extensions": "^1.35.0",
"umzug": "^2.3.0", "umzug": "^2.3.0",
"v-calendar": "^2.4.1", "v-calendar": "^2.4.2",
"vue2-leaflet": "^2.7.1", "vue2-leaflet": "^2.7.1",
"vuetify": "2.6.14", "vuetify": "2.6.14",
"winston": "^3.8.2", "winston": "^3.11.0",
"winston-daily-rotate-file": "^4.7.1", "winston-daily-rotate-file": "^4.7.1",
"yargs": "^17.7.2" "yargs": "^17.7.2"
}, },
"devDependencies": { "devDependencies": {
"@nuxtjs/vuetify": "^1.12.3", "@nuxtjs/vuetify": "^1.12.3",
"@vue/language-plugin-pug": "^1.7.0", "@vue/language-plugin-pug": "^1.8.19",
"jest": "^29.5.0", "jest": "^29.7.0",
"jest-environment-node": "^29.5.0", "jest-environment-node": "^29.7.0",
"prettier": "^2.8.8", "prettier": "^2.8.8",
"pug": "^3.0.2", "pug": "^3.0.2",
"pug-plain-loader": "^1.1.0", "pug-plain-loader": "^1.1.0",
"sass": "^1.61.0", "sass": "^1.67.0",
"sequelize-cli": "^6.3.0", "sequelize-cli": "^6.6.1",
"supertest": "^6.3.3", "supertest": "^6.3.3",
"webpack": "4", "webpack": "4",
"webpack-cli": "^4.10.0" "webpack-cli": "^4.10.0"

View file

@ -3,7 +3,8 @@ v-container.container.pa-0.pa-md-3
v-card v-card
v-alert(v-if='url!==settings.baseurl' outlined type='warning' show-icon :icon='mdiAlert') v-alert(v-if='url!==settings.baseurl' outlined type='warning' show-icon :icon='mdiAlert')
span(v-html="$t('admin.wrong_domain_warning', { url, baseurl: settings.baseurl })") span(v-html="$t('admin.wrong_domain_warning', { url, baseurl: settings.baseurl })")
v-alert(v-if='!selfReachable' outlined type='warning' show-icon :icon='mdiAlert')
span(v-html="$t('admin.not_reachable')")
v-tabs(v-model='selectedTab' show-arrows :next-icon='mdiChevronRight' :prev-icon='mdiChevronLeft') v-tabs(v-model='selectedTab' show-arrows :next-icon='mdiChevronRight' :prev-icon='mdiChevronLeft')
//- SETTINGS //- SETTINGS
@ -102,9 +103,10 @@ export default {
try { try {
const users = await $axios.$get('/users') const users = await $axios.$get('/users')
const unconfirmedEvents = await $axios.$get('/event/unconfirmed') const unconfirmedEvents = await $axios.$get('/event/unconfirmed')
return { users, unconfirmedEvents, url } const selfReachable = await $axios.$get('/reachable')
return { users, unconfirmedEvents, url, selfReachable }
} catch (e) { } catch (e) {
return { users: [], unconfirmedEvents: [], url } return { users: [], unconfirmedEvents: [], url, selfReachable: false }
} }
}, },
data () { data () {
@ -113,6 +115,7 @@ export default {
users: [], users: [],
description: '', description: '',
unconfirmedEvents: [], unconfirmedEvents: [],
selfReachable: false
} }
}, },
head () { head () {

View file

@ -105,12 +105,12 @@ export default {
return true return true
}, },
async asyncData({ params, $axios, error, $auth, $time }) { async asyncData({ query, params, $axios, error, $auth, $time, store }) {
if (params.edit) { if (params.edit) {
const data = { event: { place: {}, media: [] } } const data = { event: { place: {}, media: [] } }
data.id = params.edit data.id = params.edit
data.edit = true data.edit = query.clone ? false : true
let event let event
try { try {
event = await $axios.$get('/event/detail/' + data.id) event = await $axios.$get('/event/detail/' + data.id)
@ -138,8 +138,13 @@ export default {
data.event.title = event.title data.event.title = event.title
data.event.description = event.description data.event.description = event.description
if (data.edit) {
data.event.id = event.id data.event.id = event.id
}
data.event.tags = event.tags data.event.tags = event.tags
if (event.media && event.media.length > 0 && !data.edit) {
event.media[0].url = `${store.state.settings.baseurl}/media/${event.media[0].url}`
}
data.event.media = event.media || [] data.event.media = event.media || []
data.event.parentId = event.parentId data.event.parentId = event.parentId
data.event.recurrent = event.recurrent data.event.recurrent = event.recurrent

View file

@ -1,10 +1,10 @@
<template lang="pug"> <template lang="pug">
v-container#event.h-event.pa-2.pa-sm-2(itemscope itemtype="https://schema.org/Event" v-touch="{ left: goNext, right: goPrev }") v-container#event.h-event.pa-2.pa-sm-2(v-touch="{ left: goNext, right: goPrev }")
//- EVENT PAGE //- EVENT PAGE
//- gancio supports microformats (http://microformats.org/wiki/h-event) //- gancio supports microformats (http://microformats.org/wiki/h-event)
//- and microdata https://schema.org/Event //- and microdata https://schema.org/Event
v-row v-row(itemscope itemtype="https://schema.org/Event")
v-col.col-12.col-md-8 v-col.col-12.col-md-8
MyPicture(v-if='hasMedia' :event='event') MyPicture(v-if='hasMedia' :event='event')
.p-description.text-body-1.pa-3.rounded(v-if='!hasMedia && event.description' itemprop='description' v-html='event.description') .p-description.text-body-1.pa-3.rounded(v-if='!hasMedia && event.description' itemprop='description' v-html='event.description')
@ -19,7 +19,7 @@ v-container#event.h-event.pa-2.pa-sm-2(itemscope itemtype="https://schema.org/Ev
v-container.eventDetails v-container.eventDetails
time.dt-start(:datetime='$time.unixFormat(event.start_datetime, "yyyy-MM-dd HH:mm")' itemprop="startDate" :content='$time.unixFormat(event.start_datetime, "yyyy-MM-dd\'T\'HH:mm")') time.dt-start(:datetime='$time.unixFormat(event.start_datetime, "yyyy-MM-dd HH:mm")' itemprop="startDate" :content='$time.unixFormat(event.start_datetime, "yyyy-MM-dd\'T\'HH:mm")')
v-icon(v-text='mdiCalendar' small) v-icon(v-text='mdiCalendar' small)
strong.ml-2.text-uppercase {{$time.when(event)}} span.ml-2.text-uppercase {{$time.when(event)}}
.d-none.dt-end(v-if='event.end_datetime' itemprop="endDate" :content='$time.unixFormat(event.end_datetime,"yyyy-MM-dd\'T\'HH:mm")') {{$time.unixFormat(event.end_datetime,"yyyy-MM-dd'T'HH:mm")}} .d-none.dt-end(v-if='event.end_datetime' itemprop="endDate" :content='$time.unixFormat(event.end_datetime,"yyyy-MM-dd\'T\'HH:mm")') {{$time.unixFormat(event.end_datetime,"yyyy-MM-dd'T'HH:mm")}}
div.font-weight-light.mb-3 {{$time.from(event.start_datetime)}} div.font-weight-light.mb-3 {{$time.from(event.start_datetime)}}
small(v-if='event.parentId') ({{$time.recurrentDetail(event)}}) small(v-if='event.parentId') ({{$time.recurrentDetail(event)}})
@ -46,9 +46,6 @@ v-container#event.h-event.pa-2.pa-sm-2(itemscope itemtype="https://schema.org/Ev
v-divider v-divider
//- info & actions //- info & actions
v-list(dense nav color='transparent') v-list(dense nav color='transparent')
//- v-list-group(:append-icon='mdiChevronUp' :value='true')
//- template(v-slot:activator)
//- v-list-item.text-overline {{$t('common.actions')}}
//- copy link //- copy link
v-list-item(@click='clipboard(`${settings.baseurl}/event/${event.slug || event.id}`)') v-list-item(@click='clipboard(`${settings.baseurl}/event/${event.slug || event.id}`)')
@ -190,8 +187,6 @@ import EventAdmin from '@/components/eventAdmin'
import EmbedEvent from '@/components/embedEvent' import EmbedEvent from '@/components/embedEvent'
import EventMapDialog from '@/components/EventMapDialog' import EventMapDialog from '@/components/EventMapDialog'
const { htmlToText } = require('html-to-text')
import { mdiArrowLeft, mdiArrowRight, mdiDotsVertical, mdiCodeTags, mdiClose, mdiMap, import { mdiArrowLeft, mdiArrowRight, mdiDotsVertical, mdiCodeTags, mdiClose, mdiMap,
mdiEye, mdiEyeOff, mdiDelete, mdiRepeat, mdiLock, mdiFileDownloadOutline, mdiShareAll, mdiEye, mdiEyeOff, mdiDelete, mdiRepeat, mdiLock, mdiFileDownloadOutline, mdiShareAll,
mdiCalendarExport, mdiCalendar, mdiContentCopy, mdiMapMarker, mdiChevronUp, mdiMonitorAccount, mdiBookmark } from '@mdi/js' mdiCalendarExport, mdiCalendar, mdiContentCopy, mdiMapMarker, mdiChevronUp, mdiMonitorAccount, mdiBookmark } from '@mdi/js'
@ -314,7 +309,7 @@ export default {
return this.event.media && this.event.media.length return this.event.media && this.event.media.length
}, },
plainDescription () { plainDescription () {
return htmlToText(this.event.description && this.event.description.replace('\n', '').slice(0, 1000)) return this.event.plain_description || ''
}, },
currentAttachmentLabel () { currentAttachmentLabel () {
return get(this.selectedResource, `data.attachment[${this.currentAttachment}].name`, '') return get(this.selectedResource, `data.attachment[${this.currentAttachment}].name`, '')

View file

@ -4,13 +4,11 @@ v-container.pa-0.pa-md-3
v-card-title {{$t('common.share')}} v-card-title {{$t('common.share')}}
v-card-text v-card-text
p.text-body-1 {{$t('export.intro')}} p.text-body-1 {{$t('export.intro')}}
v-row v-card(outlined :dark='is_dark' :color="is_dark ? '#333' : '#ececec'")
v-col(:md='2' :cols='12') v-card-title {{$t('common.filter')}}
v-card-title.py-0 {{$t('common.filter')}} v-card-subtitle {{$t('export.filter_description')}}
v-col v-card-text
Search( Search(v-model='filters')
:filters='filters'
@update='f => filters = f')
v-tabs(v-model='type' show-arrows :next-icon='mdiChevronRight' :prev-icon='mdiChevronLeft') v-tabs(v-model='type' show-arrows :next-icon='mdiChevronRight' :prev-icon='mdiChevronLeft')
//- TOFIX //- TOFIX
@ -52,13 +50,14 @@ v-container.pa-0.pa-md-3
v-col.col-12.col-lg-4 v-col.col-12.col-lg-4
v-text-field(v-model='list.title' :label='$t("common.title")') v-text-field(v-model='list.title' :label='$t("common.title")')
v-text-field(v-model='list.maxEvents' type='number' min='1' :label='$t("common.max_events")') v-text-field(v-model='list.maxEvents' type='number' min='1' :label='$t("common.max_events")')
v-switch(v-model='list.theme' inset true-value='dark' false-value='light' :label="$t('admin.is_dark')") v-switch(v-model='list.theme' hide-details inset true-value='dark' false-value='light' :label="$t('admin.is_dark')")
v-switch(v-model='list.sidebar' inset true-value='true' false-value='false' :label="$t('admin.widget')") v-switch(v-model='list.sidebar' inset true-value='true' false-value='false' :label="$t('admin.widget')")
v-col.col-12.col-lg-8 v-col.col-12.col-lg-8
gancio-events(:baseurl='settings.baseurl' gancio-events(:baseurl='settings.baseurl'
:maxlength='list.maxEvents && Number(list.maxEvents)' :maxlength='list.maxEvents && Number(list.maxEvents)'
:title='list.title' :title='list.title'
:theme='list.theme' :theme='list.theme'
:collection='filters.collection'
:places='filters.places.join(",")' :places='filters.places.join(",")'
:tags='filters.tags.join(",")' :tags='filters.tags.join(",")'
:show_recurrent='filters.show_recurrent' :show_recurrent='filters.show_recurrent'
@ -81,7 +80,7 @@ v-container.pa-0.pa-md-3
</template> </template>
<script> <script>
import { mapState } from 'vuex' import { mapState, mapGetters } from 'vuex'
import FollowMe from '../components/FollowMe' import FollowMe from '../components/FollowMe'
import Search from '@/components/Search' import Search from '@/components/Search'
import clipboard from '../assets/clipboard' import clipboard from '../assets/clipboard'
@ -112,7 +111,7 @@ export default {
theme: $store.state.settings['theme.is_dark'] ? 'dark' : 'light', theme: $store.state.settings['theme.is_dark'] ? 'dark' : 'light',
sidebar: 'true' sidebar: 'true'
}, },
filters: { tags: [], places: [], show_recurrent: $store.state.settings.recurrent_event_visible }, filters: { tags: [], places: [], collection: undefined, show_recurrent: $store.state.settings.recurrent_event_visible },
events: [] events: []
} }
}, },
@ -123,6 +122,7 @@ export default {
}, },
computed: { computed: {
...mapState(['settings']), ...mapState(['settings']),
...mapGetters(['is_dark']),
code () { code () {
const params = [`baseurl="${this.settings.baseurl}"`] const params = [`baseurl="${this.settings.baseurl}"`]
@ -130,6 +130,9 @@ export default {
params.push(`title="${this.list.title}"`) params.push(`title="${this.list.title}"`)
} }
if (this.filters.collection) {
params.push(`collection="${this.filters.collection}"`)
} else {
if (this.filters.places.length) { if (this.filters.places.length) {
params.push(`places="${this.filters.places.join(',')}"`) params.push(`places="${this.filters.places.join(',')}"`)
} }
@ -137,6 +140,7 @@ export default {
if (this.filters.tags.length) { if (this.filters.tags.length) {
params.push(`tags="${this.filters.tags.join(',')}"`) params.push(`tags="${this.filters.tags.join(',')}"`)
} }
}
if (this.filters.show_recurrent) { if (this.filters.show_recurrent) {
params.push(`show_recurrent="${this.filters.show_recurrent}"`) params.push(`show_recurrent="${this.filters.show_recurrent}"`)
@ -158,6 +162,10 @@ export default {
const typeMap = ['rss', 'ics'] const typeMap = ['rss', 'ics']
const params = [] const params = []
if (this.filters.collection) {
return `${this.settings.baseurl}/feed/${typeMap[this.type]}/collection/${encodeURIComponent(this.filters.collection)}`
} else {
if (this.filters.tags.length) { if (this.filters.tags.length) {
params.push(`tags=${this.filters.tags.map(encodeURIComponent).join(',')}`) params.push(`tags=${this.filters.tags.map(encodeURIComponent).join(',')}`)
} }
@ -165,6 +173,7 @@ export default {
if (this.filters.places.length) { if (this.filters.places.length) {
params.push(`places=${this.filters.places.join(',')}`) params.push(`places=${this.filters.places.join(',')}`)
} }
}
if (this.filters.show_recurrent) { if (this.filters.show_recurrent) {
params.push('show_recurrent=true') params.push('show_recurrent=true')

View file

@ -1,5 +1,6 @@
<template lang='pug'> <template lang='pug'>
v-container v-container
v-form(@submit.prevent="change_password" v-model='valid')
v-row.mt-5(align='center' justify='center') v-row.mt-5(align='center' justify='center')
v-col(cols='12' md="6" lg="5" xl="4") v-col(cols='12' md="6" lg="5" xl="4")
v-card v-card
@ -11,14 +12,17 @@ v-container
:rules="$validators.password" :rules="$validators.password"
autofocus :placeholder='$t("common.new_password")' autofocus :placeholder='$t("common.new_password")'
v-model='new_password') v-model='new_password')
div(v-else) {{$t('recover.not_valid_code')}} template(v-else)
v-card-text
v-alert(type='error' :icon='mdiAlert') {{$t('recover.not_valid_code')}} <br/> {{ error }}
v-card-actions v-card-actions
v-spacer v-spacer
v-btn(v-if='user' text color='primary' @click='change_password') {{$t('common.send')}} v-btn(v-if='user' outlined color='primary' type='submit' :disabled='!valid') {{$t('common.send')}}
</template> </template>
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import { mdiAlert } from '@mdi/js'
export default { export default {
name: 'Recover', name: 'Recover',
@ -28,11 +32,11 @@ export default {
const user = await $axios.$post('/user/check_recover_code', { recover_code: code }) const user = await $axios.$post('/user/check_recover_code', { recover_code: code })
return { user, code } return { user, code }
} catch (e) { } catch (e) {
return { user: false } return { user: false, error: String(e) }
} }
}, },
data () { data () {
return { new_password: '' } return { new_password: '', valid: false, mdiAlert }
}, },
computed: mapState(['settings']), computed: mapState(['settings']),
methods: { methods: {

View file

@ -15,10 +15,11 @@ v-container
v-btn(color="primary" type='submit' :disabled='!new_password' @click='change_password' outlined) {{$t('common.send')}} v-btn(color="primary" type='submit' :disabled='!new_password' @click='change_password' outlined) {{$t('common.send')}}
v-card-text(v-else) v-card-text(v-else)
v-alert.ma-5(type='error') {{$t('recover.not_valid_code')}} v-alert.ma-5(type='error' :icon='mdiAlert') {{$t('recover.not_valid_code')}} <br/> {{ error }}
</template> </template>
<script> <script>
import { mdiAlert } from '@mdi/js'
export default { export default {
name: 'Recover', name: 'Recover',
@ -28,11 +29,11 @@ export default {
const user = await $axios.$post('/user/check_recover_code', { recover_code: code }) const user = await $axios.$post('/user/check_recover_code', { recover_code: code })
return { user, code } return { user, code }
} catch (e) { } catch (e) {
return { user: false } return { user: false, error: String(e) }
} }
}, },
data () { data () {
return { new_password: '' } return { new_password: '', mdiAlert }
}, },
methods: { methods: {
async change_password () { async change_password () {

View file

@ -1,9 +1,62 @@
const express = require('express')
const myPluginRouter = express.Router()
// this will answer at http://localhost:13120/api/plugin/Example/test
myPluginRouter.get('/test', (req, res) => {
return res.json('OK!')
})
const plugin = { const plugin = {
routeAPI: myPluginRouter,
configuration: {
name: 'Example',
author: 'lesion',
url: 'https://framagit.org/les/gancio',
description: 'Example plugin',
settings: {
my_plugin_string_setting: {
type: 'TEXT',
description: 'My plugin string setting',
required: true,
hint: 'My plugin setting support <strong>html too</strong>'
},
enable_this_feature_in_my_plugin: {
type: 'CHECK',
description: 'My plugin best feature',
required: true,
hint: 'This feature is super dupe, enable it!'
},
min_post: {
type: 'NUMBER',
description: 'it supports number too'
},
my_default_language: {
description: 'My default language',
type: 'LIST',
items: ['it', 'en', 'fr']
}
}
},
gancio: null, gancio: null,
load (gancio) { settings: null,
load (gancio, settings) {
console.error('Plugin GancioPluginExample loaded!') console.error('Plugin GancioPluginExample loaded!')
console.error('Your settings are in ', settings)
console.error(`For example, you can access to your default language setting by using ${settings.my_default_language}`)
plugin.gancio = gancio plugin.gancio = gancio
plugin.settings = settings
// gancio.db.models.event.findAll({ where: })
// gancio.db.query('CREATE TABLE IF NOT EXISTS ()... ')
},
unload () {
console.error('Unload this plugin!')
},
onTest () {
console.error('called on "TEST" button pressed in admin interface')
}, },
onEventCreate (event) { onEventCreate (event) {

View file

@ -4,6 +4,22 @@ export default ({ app, store }, inject) => {
Settings.defaultLocale = app.i18n.locale || store.state.settings.instance_locale Settings.defaultLocale = app.i18n.locale || store.state.settings.instance_locale
const time = { const time = {
timeFormat () {
const time = DateTime.fromObject({ hour: 14 }, {
zone: store.state.settings.instance_timezone,
locale: app.i18n.locale || store.state.settings.instance_locale
}).toLocaleString({ hour: 'numeric'})
return time === '2 PM' ? 'ampm' : '24hr'
},
formatHour (value, format) {
if (!value) return ''
return DateTime.fromFormat(value, 'HH:mm', {
zone: store.state.settings.instance_timezone,
locale: app.i18n.locale || store.state.settings.instance_locale
}).toLocaleString({ hour: '2-digit', minute: '2-digit'})
},
format (date, format) { format (date, format) {
return DateTime.fromISO(date, { return DateTime.fromISO(date, {
zone: store.state.settings.instance_timezone, zone: store.state.settings.instance_timezone,
@ -46,11 +62,11 @@ export default ({ app, store }, inject) => {
} }
const start = DateTime.fromSeconds(event.start_datetime, opt) const start = DateTime.fromSeconds(event.start_datetime, opt)
let time = start.toFormat('EEEE d MMMM HH:mm') let time = start.toLocaleString({ weekday: 'long', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' })
const end = event.end_datetime && DateTime.fromSeconds(event.end_datetime, opt) const end = event.end_datetime && DateTime.fromSeconds(event.end_datetime, opt)
if (end) { if (end) {
time += event.multidate ? `${end.toFormat('EEEE d MMMM')}` : `-${end.toFormat('HH:mm')}` time += event.multidate ? `${end.toLocaleString({ weekday: 'long', month: 'short', day: '2-digit'})}` : `-${end.toLocaleString({hour: '2-digit', minute: '2-digit'})}`
} }
if (currentYear !== start.year) { if (currentYear !== start.year) {
@ -73,14 +89,18 @@ export default ({ app, store }, inject) => {
recurrentDetail (event) { recurrentDetail (event) {
const opt = {
zone,
locale: app.i18n.locale || store.state.settings.instance_locale
}
const parent = event.parent const parent = event.parent
if (!parent.recurrent || !parent.recurrent.frequency) return 'error!' if (!parent.recurrent || !parent.recurrent.frequency) return 'error!'
const { frequency, type } = parent.recurrent const { frequency, type } = parent.recurrent
let recurrent let recurrent
if (frequency === '1w' || frequency === '2w') { if (frequency === '1w' || frequency === '2w') {
recurrent = app.i18n.t(`event.recurrent_${frequency}_days`, { days: DateTime.fromSeconds(parent.start_datetime).toFormat('EEEE') }) recurrent = app.i18n.t(`event.recurrent_${frequency}_days`, { days: DateTime.fromSeconds(parent.start_datetime, opt).toFormat('EEEE')})
} else if (frequency === '1m' || frequency === '2m') { } else if (frequency === '1m' || frequency === '2m') {
const d = type === 'ordinal' ? DateTime.fromSeconds(parent.start_datetime).day : DateTime.fromSeconds(parent.start_datetime).toFormat('EEEE') const d = type === 'ordinal' ? DateTime.fromSeconds(parent.start_datetime, opt).day : DateTime.fromSeconds(parent.start_datetime, opt).toFormat('EEEE')
if (type === 'ordinal') { if (type === 'ordinal') {
recurrent = app.i18n.t(`event.recurrent_${frequency}_days`, { days: d }) recurrent = app.i18n.t(`event.recurrent_${frequency}_days`, { days: d })
} else { } else {
@ -116,6 +136,7 @@ export default ({ app, store }, inject) => {
const now = DateTime.local(opt).toUnixInteger() const now = DateTime.local(opt).toUnixInteger()
for (const e of events) { for (const e of events) {
const tmp = DateTime.fromSeconds(e.start_datetime, opt) const tmp = DateTime.fromSeconds(e.start_datetime, opt)
if (!tmp || !tmp.year) continue
const start = DateTime.local().set({ year: tmp.year, month: tmp.month, day: tmp.day }) const start = DateTime.local().set({ year: tmp.year, month: tmp.month, day: tmp.day })
// merge events with same date // merge events with same date
const key = `${start.month}${start.day}` const key = `${start.month}${start.day}`

View file

@ -1,14 +1,15 @@
const { Collection, Filter, Event, Tag, Place } = require('../models/models') const { Collection, Filter, Event, Tag, Place } = require('../models/models')
const exportController = require('./export')
const log = require('../../log') const log = require('../../log')
const { DateTime } = require('luxon') const { DateTime } = require('luxon')
const { col: Col } = require('../../helpers') const { col: Col, queryParamToBool } = require('../../helpers')
const { Op, Sequelize } = require('sequelize') const { Op, Sequelize } = require('sequelize')
const collectionController = { const collectionController = {
async getAll (req, res) { async getAll (req, res) {
const withFilters = req.query.withFilters const withFilters = queryParamToBool(req.query.withFilters)
let collections let collections
if (withFilters) { if (withFilters) {
collections = await Collection.findAll({ include: [ Filter ] }) collections = await Collection.findAll({ include: [ Filter ] })
@ -19,18 +20,39 @@ const collectionController = {
return res.json(collections) return res.json(collections)
}, },
// return events from collection
async getEvents (req, res) { async getEvents (req, res) {
const name = req.params.name const name = req.params.name
const format = req.params.format || 'json'
try {
const events = await collectionController._getEvents(name)
switch (format) {
case 'rss':
return exportController.feed(req, res, events,
`${res.locals.settings.title} - Collection @${name}`,
`${res.locals.settings.baseurl}/feed/rss/collection/${name}`)
case 'ics':
return exportController.ics(req, res, events)
default:
return res.json(events )
}
} catch (e) {
log.error(e)
return res.sendStatus(404)
}
},
// return events from collection
async _getEvents (name) {
const collection = await Collection.findOne({ where: { name } }) const collection = await Collection.findOne({ where: { name } })
if (!collection) { if (!collection) {
return res.sendStatus(404) throw new Error(`Collection ${name} not found`)
} }
const filters = await Filter.findAll({ where: { collectionId: collection.id } })
const filters = await Filter.findAll({ where: { collectionId: collection.id } })
if (!filters.length) { if (!filters.length) {
return res.json([]) return []
} }
const start = DateTime.local().toUnixInteger() const start = DateTime.local().toUnixInteger()
const where = { const where = {
@ -40,10 +62,7 @@ const collectionController = {
// confirmed event only // confirmed event only
is_visible: true, is_visible: true,
// [Op.or]: {
start_datetime: { [Op.gte]: start }, start_datetime: { [Op.gte]: start },
// end_datetime: { [Op.gte]: start }
// }
} }
const replacements = [] const replacements = []
@ -67,7 +86,7 @@ const collectionController = {
const events = await Event.findAll({ const events = await Event.findAll({
where, where,
attributes: { attributes: {
exclude: ['likes', 'boost', 'userId', 'is_visible', 'createdAt', 'updatedAt', 'description', 'resources'] exclude: ['likes', 'boost', 'userId', 'is_visible', 'createdAt', 'description', 'resources']
}, },
order: ['start_datetime'], order: ['start_datetime'],
include: [ include: [
@ -86,14 +105,12 @@ const collectionController = {
return [] return []
}) })
const ret = events.map(e => { return events.map(e => {
e = e.get() e = e.get()
e.tags = e.tags ? e.tags.map(t => t && t.tag) : [] e.tags = e.tags ? e.tags.map(t => t && t.tag) : []
return e return e
}) })
return res.json(ret)
}, },
async add (req, res) { async add (req, res) {

View file

@ -9,8 +9,9 @@ const { DateTime } = require('luxon')
const helpers = require('../../helpers') const helpers = require('../../helpers')
const Col = helpers.col const Col = helpers.col
const notifier = require('../../notifier') const notifier = require('../../notifier')
const { htmlToText } = require('html-to-text')
const { Event, Resource, Tag, Place, Notification, APUser } = require('../models/models') const { Event, Resource, Tag, Place, Notification, APUser, Collection } = require('../models/models')
const exportController = require('./export') const exportController = require('./export')
@ -47,7 +48,7 @@ const eventController = {
}, },
async searchMeta(req, res) { async searchMeta(req, res) {
const search = req.query.search const search = req.query.search.toLocaleLowerCase()
const places = await Place.findAll({ const places = await Place.findAll({
order: [[Sequelize.col('w'), 'DESC']], order: [[Sequelize.col('w'), 'DESC']],
@ -74,6 +75,7 @@ const eventController = {
raw: true raw: true
}) })
const ret = places.map(p => { const ret = places.map(p => {
p.type = 'place' p.type = 'place'
return p return p
@ -181,6 +183,8 @@ const eventController = {
event.next = next && (next.slug || next.id) event.next = next && (next.slug || next.id)
event.prev = prev && (prev.slug || prev.id) event.prev = prev && (prev.slug || prev.id)
event.tags = event.tags.map(t => t.tag) event.tags = event.tags.map(t => t.tag)
event.plain_description = htmlToText(event.description, event.description.replace('\n', '').slice(0, 1000) )
if (format === 'json') { if (format === 'json') {
res.json(event) res.json(event)
} else if (format === 'ics') { } else if (format === 'ics') {
@ -315,6 +319,26 @@ const eventController = {
return res.status(400).send(`${missing_field} required`) return res.status(400).send(`${missing_field} required`)
} }
// validate start_datetime and end_datetime
if (body.end_datetime) {
if (body.start_datetime > body.end_datetime) {
return res.status(400).send(`start datetime is greater than end datetime`)
}
if (Number(body.end_datetime) > 1000*24*60*60*365) {
return res.status(400).send('are you sure?')
}
}
if (!Number(body.start_datetime)) {
return res.status(400).send(`Wrong format for start datetime`)
}
if (Number(body.start_datetime) > 1000*24*60*60*365) {
return res.status(400).send('are you sure?')
}
// find or create the place // find or create the place
let place let place
try { try {
@ -597,6 +621,8 @@ const eventController = {
} }
if (query) { if (query) {
query = query.toLocaleLowerCase()
replacements.push(query)
replacements.push(query) replacements.push(query)
where[Op.or] = where[Op.or] =
[ [
@ -690,7 +716,7 @@ const eventController = {
const parentStartDatetime = DateTime.fromSeconds(e.start_datetime) const parentStartDatetime = DateTime.fromSeconds(e.start_datetime)
// cursor is when start to count // cursor is when start to count
// sets it to // in case parent is in past, start to calculate from now
let cursor = parentStartDatetime > startAt ? parentStartDatetime : startAt let cursor = parentStartDatetime > startAt ? parentStartDatetime : startAt
startAt = cursor startAt = cursor
@ -711,6 +737,8 @@ const eventController = {
cursor = cursor.plus({ days: 7 * Number(frequency[0]) }) cursor = cursor.plus({ days: 7 * Number(frequency[0]) })
} }
} else if (frequency === '1m') { } else if (frequency === '1m') {
// day n.X each month
if (type === 'ordinal') { if (type === 'ordinal') {
cursor = cursor.set({ day: parentStartDatetime.day }) cursor = cursor.set({ day: parentStartDatetime.day })
@ -718,7 +746,7 @@ const eventController = {
cursor = cursor.plus({ months: 1 }) cursor = cursor.plus({ months: 1 })
} }
} else { // weekday } else { // weekday
// get weekday
// get recurrent freq details // get recurrent freq details
cursor = helpers.getWeekdayN(cursor, type, parentStartDatetime.weekday) cursor = helpers.getWeekdayN(cursor, type, parentStartDatetime.weekday)
if (cursor < startAt) { if (cursor < startAt) {

View file

@ -4,6 +4,7 @@ const { htmlToText } = require('html-to-text')
const { Op, literal } = require('sequelize') const { Op, literal } = require('sequelize')
const { DateTime } = require('luxon') const { DateTime } = require('luxon')
const ics = require('ics') const ics = require('ics')
const collectionController = require('./collection')
const exportController = { const exportController = {
@ -11,6 +12,7 @@ const exportController = {
const format = req.params.format const format = req.params.format
const tags = req.query.tags const tags = req.query.tags
const places = req.query.places const places = req.query.places
const collection = req.query.collection
const show_recurrent = !!req.query.show_recurrent const show_recurrent = !!req.query.show_recurrent
const opt = { const opt = {
@ -21,6 +23,7 @@ const exportController = {
const where = {} const where = {}
const yesterday = DateTime.local(opt).minus({day: 1}).toUnixInteger() const yesterday = DateTime.local(opt).minus({day: 1}).toUnixInteger()
if (!collection) {
if (tags && places) { if (tags && places) {
where[Op.or] = { where[Op.or] = {
@ -37,11 +40,19 @@ const exportController = {
where.placeId = places.split(',') where.placeId = places.split(',')
} }
}
if (!show_recurrent) { if (!show_recurrent) {
where.parentId = null where.parentId = null
} }
const events = await Event.findAll({ let events = []
if (collection) {
events = await collectionController._getEvents(collection)
console.error(events.map(e => e))
} else {
events = await Event.findAll({
order: ['start_datetime'], order: ['start_datetime'],
attributes: { exclude: ['is_visible', 'recurrent', 'createdAt', 'likes', 'boost', 'userId', 'placeId'] }, attributes: { exclude: ['is_visible', 'recurrent', 'createdAt', 'likes', 'boost', 'userId', 'placeId'] },
where: { where: {
@ -60,6 +71,7 @@ const exportController = {
}, },
{ model: Place, attributes: ['name', 'id', 'address'] }] { model: Place, attributes: ['name', 'id', 'address'] }]
}) })
}
switch (format) { switch (format) {
case 'rss': case 'rss':
@ -109,11 +121,11 @@ const exportController = {
endInputType: 'utc', endInputType: 'utc',
title: `[${settings.title}] ${e.title}`, title: `[${settings.title}] ${e.title}`,
description: htmlToText(e.description), description: htmlToText(e.description),
htmlContent: e.description.replace(/\n/g,"<br>"), htmlContent: e.description && e.description.replace(/\n/g,"<br>"),
location, location,
url: `${settings.baseurl}/event/${e.slug || e.id}`, url: `${settings.baseurl}/event/${e.slug || e.id}`,
status: 'CONFIRMED', status: 'CONFIRMED',
categories: e.tags.map(t => t.tag), categories: e.tags.map(t => t.tag || t),
alarms alarms
} }

View file

@ -4,6 +4,7 @@ const log = require('../../log')
const config = require('../../config') const config = require('../../config')
const settingsController = require('./settings') const settingsController = require('./settings')
const notifier = require('../../notifier') const notifier = require('../../notifier')
const db = require('../models/index.js')
const pluginController = { const pluginController = {
plugins: [], plugins: [],
@ -32,6 +33,22 @@ const pluginController = {
res.json() res.json()
}, },
async routeAPI (req, res, next) {
const pluginName = req.params.plugin
const plugin = pluginController.plugins.find(p => p.configuration.name === pluginName)
if (!plugin) {
log.warn(`Plugin ${pluginName} not found`)
return res.sendStatus(404)
}
if (typeof plugin.routeAPI !== 'function') {
log.warn(`Plugin ${pluginName} does not expose a 'routeAPI' function`)
return res.sendStatus(404)
}
return plugin.routeAPI(req, res, next)
},
async testPlugin (req, res) { async testPlugin (req, res) {
const pluginName = req.params.plugin const pluginName = req.params.plugin
const plugin = pluginController.plugins.find(p => p.configuration.name === pluginName) const plugin = pluginController.plugins.find(p => p.configuration.name === pluginName)
@ -69,7 +86,7 @@ const pluginController = {
} }
if (plugin.unload && typeof plugin.unload === 'function') { if (plugin.unload && typeof plugin.unload === 'function') {
plugin.unload({ settings: settingsController.settings }, settings) plugin.unload()
} }
}, },
@ -96,7 +113,8 @@ const pluginController = {
plugin.load({ plugin.load({
helpers: require('../../helpers'), helpers: require('../../helpers'),
log, log,
settings: settingsController.settings settings: settingsController.settings,
db: db.sequelize
}, },
settings) settings)
} }
@ -116,6 +134,8 @@ const pluginController = {
const pluginSetting = settingsController.settings['plugin_' + name] const pluginSetting = settingsController.settings['plugin_' + name]
if (pluginSetting.enable) { if (pluginSetting.enable) {
pluginController.loadPlugin(name) pluginController.loadPlugin(name)
} else {
log.info(`Do not load plugin ${name} (${pluginFile}) as it is not enabled!`)
} }
} else { } else {
settingsController.set('plugin_' + name, { enable: false }) settingsController.set('plugin_' + name, { enable: false })

View file

@ -11,7 +11,7 @@ const userController = {
async forgotPassword (req, res) { async forgotPassword (req, res) {
const email = req.body.email const email = req.body.email
const user = await User.findOne({ where: { email: { [Op.eq]: email } } }) const user = await User.findOne({ where: { email, is_active: true } })
if (!user) { return res.sendStatus(200) } if (!user) { return res.sendStatus(200) }
user.recover_code = crypto.randomBytes(16).toString('hex') user.recover_code = crypto.randomBytes(16).toString('hex')
@ -62,13 +62,9 @@ const userController = {
if (!user) { return res.status(404).json({ success: false, message: 'User not found!' }) } if (!user) { return res.status(404).json({ success: false, message: 'User not found!' }) }
if (req.body.id !== req.user.id && !req.user.is_admin) {
return res.status(400).json({ succes: false, message: 'Not allowed' })
}
if (!req.body.password) { delete req.body.password } if (!req.body.password) { delete req.body.password }
if (!user.is_active && req.body.is_active && user.recover_code) { if ((!user.is_active && req.body.is_active) || user.recover_code) {
mail.send(user.email, 'confirm', { user, config }, res.locals.settings.locale) mail.send(user.email, 'confirm', { user, config }, res.locals.settings.locale)
} }
@ -89,6 +85,7 @@ const userController = {
} }
req.body.is_active = false req.body.is_active = false
req.body.is_admin = false
// check email // check email
if (!linkify.test(req.body.email, 'email')) { if (!linkify.test(req.body.email, 'email')) {

View file

@ -70,6 +70,7 @@ module.exports = () => {
``` ```
*/ */
api.get('/ping', (_req, res) => res.sendStatus(200)) api.get('/ping', (_req, res) => res.sendStatus(200))
api.get('/reachable', helpers.reachable)
api.get('/user', isAuth, (req, res) => res.json(req.user)) api.get('/user', isAuth, (req, res) => res.json(req.user))
api.post('/user/recover', SPAMProtectionApiRateLimiter, userController.forgotPassword) api.post('/user/recover', SPAMProtectionApiRateLimiter, userController.forgotPassword)
@ -81,7 +82,7 @@ module.exports = () => {
api.post('/user', isAdmin, userController.create) api.post('/user', isAdmin, userController.create)
// update user // update user
api.put('/user', isAuth, userController.update) api.put('/user', isAdmin, userController.update)
// delete user // delete user
api.delete('/user/:id', isAdmin, userController.remove) api.delete('/user/:id', isAdmin, userController.remove)
@ -145,7 +146,7 @@ module.exports = () => {
// remove event // remove event
api.delete('/event/:id', isAuth, eventController.remove) api.delete('/event/:id', isAuth, eventController.remove)
// get tags/places // get tags/places/collection
api.get('/event/meta', eventController.searchMeta) api.get('/event/meta', eventController.searchMeta)
// add event notification TODO // add event notification TODO
@ -223,6 +224,8 @@ module.exports = () => {
api.post('/plugin/test/:plugin', isAdmin, pluginController.testPlugin) api.post('/plugin/test/:plugin', isAdmin, pluginController.testPlugin)
api.put('/plugin/:plugin', isAdmin, pluginController.togglePlugin) api.put('/plugin/:plugin', isAdmin, pluginController.togglePlugin)
api.use('/plugin/:plugin', pluginController.routeAPI)
// OAUTH // OAUTH
api.get('/clients', isAuth, oauthController.getClients) api.get('/clients', isAuth, oauthController.getClients)
api.get('/client/:client_id', isAuth, oauthController.getClient) api.get('/client/:client_id', isAuth, oauthController.getClient)

View file

@ -21,11 +21,11 @@ const instanceApiRateLimiter = {
* (used during the registration, pass recovery, posting events) */ * (used during the registration, pass recovery, posting events) */
SPAMProtectionApiRateLimiter: (process.env.NODE_ENV === 'test' ? next : rateLimit({ SPAMProtectionApiRateLimiter: (process.env.NODE_ENV === 'test' ? next : rateLimit({
windowMs: 5 * 60 * 1000, // 5 minutes windowMs: 5 * 60 * 1000, // 5 minutes
max: 3, // Limit each IP to 3 requests per `window` (here, per 5 minutes) max: 6, // Limit each IP to 3 requests per `window` (here, per 5 minutes)
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
legacyHeaders: false, // Disable the `X-RateLimit-*` headers legacyHeaders: false, // Disable the `X-RateLimit-*` headers
handler: (request, response, next, options) => { handler: (request, response, next, options) => {
log.warn(`SPAM protection api rate limiter: 3req/5min/ip ${request.ip}`) log.warn(`SPAM protection api rate limiter: 6req/5min/ip ${request.ip}`)
return response.status(options.statusCode).send(options.message) return response.status(options.statusCode).send(options.message)
} }
})) }))

View file

@ -37,7 +37,7 @@ const mail = {
} }
}, },
message: { message: {
from: `📅 ${settings.title} <${settings.admin_email}>` from: `"📅 ${settings.title}" <${settings.admin_email}>`
}, },
send: true, send: true,
i18n: { i18n: {
@ -49,7 +49,7 @@ const mail = {
locale, locale,
locales: Object.keys(locales) locales: Object.keys(locales)
}, },
transport: settings.smtp || {} transport: { ...settings.smtp, tls: { ciphers: 'SSLv3'}, requireTLS: true } || {}
}) })
const opt = { const opt = {

View file

@ -72,6 +72,7 @@ module.exports = (sequelize, DataTypes) => {
startTime: DateTime.fromSeconds(this.start_datetime, opt).toISO(), startTime: DateTime.fromSeconds(this.start_datetime, opt).toISO(),
...( this.end_datetime ? { endTime : DateTime.fromSeconds(this.end_datetime, opt).toISO() } : {} ), ...( this.end_datetime ? { endTime : DateTime.fromSeconds(this.end_datetime, opt).toISO() } : {} ),
location: { location: {
type: 'Place',
name: this.place.name, name: this.place.name,
address: this.place.address, address: this.place.address,
latitude: this.place.latitude, latitude: this.place.latitude,

View file

@ -6,7 +6,7 @@ const config = require('../../config')
const log = require('../../log') const log = require('../../log')
const SequelizeSlugify = require('sequelize-slugify') const SequelizeSlugify = require('sequelize-slugify')
const DB = require('./models') const DB = require('./models')
const semver = require('semver')
const models = { const models = {
Announcement: require('./announcement'), Announcement: require('./announcement'),
APUser: require('./ap_user'), APUser: require('./ap_user'),
@ -107,8 +107,39 @@ const db = {
return true return true
} }
}, },
async fixMariaDBJSON () {
// manually fix mariadb JSON wrong parse
if (db.sequelize.options.dialect === 'mariadb' && semver.lt('10.5.2', db.sequelize.options.databaseVersion)) {
try {
const ret = await db.sequelize.query('SHOW CREATE TABLE `settings`')
if (!ret[0][0]['Create Table'].toLowerCase().includes('json_valid')){
await db.sequelize.query('alter table settings modify `value` JSON')
await db.sequelize.query('alter table ap_users modify `object` JSON')
await db.sequelize.query('alter table events modify `recurrent` JSON')
await db.sequelize.query('alter table events modify `likes` JSON')
await db.sequelize.query('alter table events modify `boost` JSON')
await db.sequelize.query('alter table events modify `media` JSON')
await db.sequelize.query('alter table events modify `online_locations` JSON')
await db.sequelize.query('alter table filters modify `tags` JSON')
await db.sequelize.query('alter table filters modify `places` JSON')
await db.sequelize.query('alter table instances modify `data` JSON')
await db.sequelize.query('alter table notifications modify `filters` JSON')
await db.sequelize.query('alter table resources modify `data` JSON')
await db.sequelize.query('alter table users modify `settings` JSON')
await db.sequelize.query('alter table users modify `rsa` JSON')
log.info(`MariaDB JSON migrations done`)
} else {
log.debug('MariaDB JSON issue already fixed')
}
} catch (e) {
console.error(e)
}
}
},
async runMigrations() { async runMigrations() {
const logging = config.status !== 'READY' ? false : log.debug.bind(log) const logging = config.status !== 'READY' ? false : log.debug.bind(log)
const umzug = new Umzug({ const umzug = new Umzug({
storage: 'sequelize', storage: 'sequelize',
storageOptions: { sequelize: db.sequelize }, storageOptions: { sequelize: db.sequelize },

View file

@ -1,7 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
const pkg = require('../package.json') const pkg = require('../package.json')
const path = require('path') const path = require('path')
const accountsCLI = require('./cli/accounts') const usersCLI = require('./cli/users')
process.env.cwd = process.env.GANCIO_DATA || path.resolve('./') process.env.cwd = process.env.GANCIO_DATA || path.resolve('./')
@ -29,7 +29,7 @@ require('yargs')
return absolute_config_path return absolute_config_path
}}) }})
.command(['start', 'run', '$0'], 'Start gancio', {}, start) .command(['start', 'run', '$0'], 'Start gancio', {}, start)
.command(['accounts'], 'Manage accounts', accountsCLI) .command(['users'], 'Manage users', usersCLI)
.help('h') .help('h')
.alias('h', 'help') .alias('h', 'help')
.epilog('Made with ❤ by underscore hacklab - https://gancio.org') .epilog('Made with ❤ by underscore hacklab - https://gancio.org')

View file

@ -1,92 +0,0 @@
let db
function _initializeDB () {
const config = require('../config')
config.log_level = 'error'
db = require('../api/models/index')
return db.initialize()
}
async function modify (args) {
await _initializeDB()
const helpers = require('../helpers')
const { User } = require('../api/models/models')
const user = await User.findOne({ where: { email: args.account } })
console.log()
if (!user) {
console.error(`User ${args.account} not found`)
return
}
if (args['reset-password']) {
const password = helpers.randomString()
user.password = password
await user.save()
console.log(`New password for user ${user.email} is '${password}'`)
}
if (args.admin) {
user.is_admin = true
await user.save()
}
await db.close()
}
async function create (args) {
await _initializeDB()
const { User } = require('../api/models/models')
const user = await User.create({
email: args.email,
is_active: true,
is_admin: args.admin || false
}).catch(e => console.error(String(e)))
console.error(JSON.stringify(user, null, 2))
await db.close()
}
async function remove (args) {
await _initializeDB()
const { User } = require('../api/models/models')
const user = await User.findOne({
where: { email: args.email }
})
if (user) {
await user.destroy()
}
await db.close()
}
async function list () {
await _initializeDB()
const { User } = require('../api/models/models')
const users = await User.findAll()
console.log()
users.forEach(u => console.log(`${u.id}\tadmin: ${u.is_admin}\tenabled: ${u.is_active}\temail: ${u.email}`))
console.log()
await db.close()
}
const accountsCLI = yargs => yargs
.command('list', 'List all accounts', list)
.command('modify', 'Modify', {
account: {
describe: 'Account to modify',
type: 'string',
demandOption: true
},
'reset-password': {
describe: 'Resets the password of the given account ',
type: 'boolean'
},
admin: { describe: 'Define this account as administrator', type: 'boolean' }
}, modify)
.command('create <email|username> [admin]', 'Create an account', {
admin: { describe: 'Define this account as administrator', type: 'boolean' }
}, create)
.command('remove <email|username>', 'Remove an account', {}, remove)
.positional('email', { describe: 'account email or username', type: 'string', demandOption: true })
.recommendCommands()
.demandCommand(1, '')
.argv
module.exports = accountsCLI

124
server/cli/users.js Normal file
View file

@ -0,0 +1,124 @@
let db
function _initializeDB () {
const config = require('../config')
if (config.status !== 'CONFIGURED') {
console.error(`> Cannot run CLI before setup (are you in the correct path?)`)
process.exit(1)
}
config.log_level = 'error'
db = require('../api/models/index')
return db.initialize()
}
async function setAdmin (args) {
await _initializeDB()
const { User } = require('../api/models/models')
const user = await User.findOne({ where: { email: args.email } })
console.log()
if (!user) {
console.error(`User ${args.email} not found`)
return
}
user.is_admin = true
await user.save()
console.log(`User ${user.email} is now an administrator!`)
await db.close()
}
async function unsetAdmin (args) {
await _initializeDB()
const helpers = require('../helpers')
const { User } = require('../api/models/models')
const user = await User.findOne({ where: { email: args.email } })
console.log()
if (!user) {
console.error(`User ${args.email} not found`)
return
}
user.is_admin = false
await user.save()
console.log(`User ${user.email} is not an administrator anymore!`)
await db.close()
}
async function resetPassword (args) {
await _initializeDB()
const helpers = require('../helpers')
const { User } = require('../api/models/models')
const user = await User.findOne({ where: { email: args.email } })
console.log()
if (!user) {
console.error(`User ${args.email} not found`)
return
}
const password = helpers.randomString()
user.password = password
await user.save()
console.log(`New password for user ${user.email} is '${password}'`)
await db.close()
}
async function create (args) {
await _initializeDB()
const { User } = require('../api/models/models')
try {
const user = await User.create({
email: args.email,
password: args.password,
is_active: true,
is_admin: args.admin || false
})
console.error(`User ${args.email} created`)
} catch(e) {
console.error(String(e))
}
await db.close()
}
async function remove (args) {
await _initializeDB()
const { User } = require('../api/models/models')
const user = await User.findOne({
where: { email: args.email }
})
if (user) {
await user.destroy()
console.error(`User "${args.email}" succesfully removed`)
} else {
console.error(`User "${args.email}" not found!`)
}
await db.close()
}
async function list () {
await _initializeDB()
const { User } = require('../api/models/models')
const users = await User.findAll()
console.log()
users.forEach(u => console.log(`${u.id}\tadmin: ${u.is_admin}\tenabled: ${u.is_active}\temail: ${u.email}`))
console.log()
await db.close()
}
const usersCLI = yargs => yargs
.command('list', 'List all users', list)
.command('reset-password <email|username>', 'Resets the password of the given user', {
}, resetPassword)
.command('set-admin <email|username>', 'Set administrator privileges to the given user', {}, setAdmin)
.command('unset-admin <email|username>', 'Remove administrator privileges to the given user', {}, unsetAdmin)
.command('create <email|username> [password] [admin]', 'Create an user', {
admin: { describe: 'Define this user as administrator', type: 'boolean' },
}, create)
.command('remove <email|username>', 'Remove an user', {}, remove)
.positional('email', { describe: 'user email or username', type: 'string', demandOption: true })
.positional('password', { describe: 'Password', type: 'string', demandOption: false })
.recommendCommands()
.demandCommand(1, '')
.argv
module.exports = usersCLI

View file

@ -44,7 +44,7 @@ let config = {
} }
} else { } else {
config.status = 'SETUP' config.status = 'SETUP'
console.info('> Configuration file does not exists, running setup..') console.info('> Configuration file does not exists...')
} }
} }
} }

View file

@ -36,7 +36,14 @@ router.get('/m/:event_id', async (req, res) => {
if (!event) { return res.status(404).send('Not found') } if (!event) { return res.status(404).send('Not found') }
const eventAp = event.toAP(settingsController.settings) const eventAp = event.toAP(settingsController.settings)
eventAp['@context'] = [ eventAp['@context'] = [
"https://www.w3.org/ns/activitystreams" "https://www.w3.org/ns/activitystreams",
{
"sc": "http://schema.org/",
"address": {
"@id": "sc:address",
"@type": "sc:Text"
}
}
] ]
res.type('application/activity+json; charset=utf-8') res.type('application/activity+json; charset=utf-8')

View file

@ -258,8 +258,8 @@ module.exports = {
} }
} else { } else {
cursor = date.startOf('month') cursor = date.startOf('month')
cursor = cursor.add(cursor.day() <= date.day() ? n - 1 : n, 'week') // cursor = cursor.add(cursor.day <= date.day ? n - 1 : n, 'week')
cursor = cursor.plus({ days: cursor.weekday <= date.weekday ? (n-1) * 7 : n * 7}) cursor = cursor.plus({ weeks: cursor.weekday <= weekday ? n-1 : n })
cursor = cursor.set({ weekday }) cursor = cursor.set({ weekday })
} }
cursor = cursor.set({ hour: date.hour, minute: date.minute, second: 0 }) cursor = cursor.set({ hour: date.hour, minute: date.minute, second: 0 })
@ -287,11 +287,26 @@ module.exports = {
next() next()
}, },
async reachable(req, res) {
try {
const response = await axios({ url: config.baseurl })
return res.sendStatus(200)
} catch(e) {
return res.status(400).json(e)
}
},
async isGeocodingEnabled(req, res, next) { async isGeocodingEnabled(req, res, next) {
if (res.locals.settings.allow_geolocation) { if (res.locals.settings.allow_geolocation) {
next() next()
} else { } else {
res.sendStatus(403) res.sendStatus(403)
} }
},
queryParamToBool (value, defaultValue) {
if (typeof value === 'undefined') return defaultValue
return (String(value).toLowerCase() === 'true')
} }
} }

View file

@ -30,6 +30,7 @@ const initialize = {
await db.sequelize.authenticate() await db.sequelize.authenticate()
log.debug('Running migrations') log.debug('Running migrations')
await db.runMigrations() await db.runMigrations()
await db.fixMariaDBJSON()
await settingsController.load() await settingsController.load()
config.status = 'READY' config.status = 'READY'
} else { } else {

View file

@ -25,10 +25,10 @@ function ye(t) {
function u(t, e) { function u(t, e) {
t.appendChild(e); t.appendChild(e);
} }
function p(t, e, i) { function k(t, e, i) {
t.insertBefore(e, i || null); t.insertBefore(e, i || null);
} }
function k(t) { function x(t) {
t.parentNode.removeChild(t); t.parentNode.removeChild(t);
} }
function be(t, e) { function be(t, e) {
@ -38,14 +38,14 @@ function be(t, e) {
function m(t) { function m(t) {
return document.createElement(t); return document.createElement(t);
} }
function $(t) { function z(t) {
return document.createTextNode(t); return document.createTextNode(t);
} }
function M() { function C() {
return $(" "); return z(" ");
} }
function pe() { function pe() {
return $(""); return z("");
} }
function a(t, e, i) { function a(t, e, i) {
i == null ? t.removeAttribute(e) : t.getAttribute(e) !== i && t.setAttribute(e, i); i == null ? t.removeAttribute(e) : t.getAttribute(e) !== i && t.setAttribute(e, i);
@ -69,25 +69,25 @@ let O;
function I(t) { function I(t) {
O = t; O = t;
} }
function $e() { function Ee() {
if (!O) if (!O)
throw new Error("Function called outside component initialization"); throw new Error("Function called outside component initialization");
return O; return O;
} }
function ke(t) { function ke(t) {
$e().$$.on_mount.push(t); Ee().$$.on_mount.push(t);
} }
const R = [], Z = [], P = [], ee = [], Ee = Promise.resolve(); const R = [], Z = [], P = [], ee = [], $e = Promise.resolve();
let K = !1; let K = !1;
function je() { function je() {
K || (K = !0, Ee.then(x)); K || (K = !0, $e.then(y));
} }
function Q(t) { function Q(t) {
P.push(t); P.push(t);
} }
const J = /* @__PURE__ */ new Set(); const J = /* @__PURE__ */ new Set();
let D = 0; let D = 0;
function x() { function y() {
const t = O; const t = O;
do { do {
for (; D < R.length; ) { for (; D < R.length; ) {
@ -120,8 +120,8 @@ function Ce(t, e) {
function Ae(t, e, i, l) { function Ae(t, e, i, l) {
const { fragment: n, on_mount: r, on_destroy: o, after_update: f } = t.$$; const { fragment: n, on_mount: r, on_destroy: o, after_update: f } = t.$$;
n && n.m(e, i), l || Q(() => { n && n.m(e, i), l || Q(() => {
const c = r.map(W).filter(ge); const s = r.map(W).filter(ge);
o ? o.push(...c) : U(c), t.$$.on_mount = []; o ? o.push(...s) : U(s), t.$$.on_mount = [];
}), f.forEach(Q); }), f.forEach(Q);
} }
function Me(t, e) { function Me(t, e) {
@ -132,9 +132,9 @@ function Ne(t, e) {
t.$$.dirty[0] === -1 && (R.push(t), je(), t.$$.dirty.fill(0)), t.$$.dirty[e / 31 | 0] |= 1 << e % 31; t.$$.dirty[0] === -1 && (R.push(t), je(), t.$$.dirty.fill(0)), t.$$.dirty[e / 31 | 0] |= 1 << e % 31;
} }
function we(t, e, i, l, n, r, o, f = [-1]) { function we(t, e, i, l, n, r, o, f = [-1]) {
const c = O; const s = O;
I(t); I(t);
const s = t.$$ = { const c = t.$$ = {
fragment: null, fragment: null,
ctx: null, ctx: null,
props: r, props: r,
@ -146,26 +146,26 @@ function we(t, e, i, l, n, r, o, f = [-1]) {
on_disconnect: [], on_disconnect: [],
before_update: [], before_update: [],
after_update: [], after_update: [],
context: new Map(e.context || (c ? c.$$.context : [])), context: new Map(e.context || (s ? s.$$.context : [])),
callbacks: Y(), callbacks: Y(),
dirty: f, dirty: f,
skip_bound: !1, skip_bound: !1,
root: e.target || c.$$.root root: e.target || s.$$.root
}; };
o && o(s.root); o && o(c.root);
let w = !1; let w = !1;
if (s.ctx = i ? i(t, e.props || {}, (g, _, ...A) => { if (c.ctx = i ? i(t, e.props || {}, (g, _, ...A) => {
const y = A.length ? A[0] : _; const E = A.length ? A[0] : _;
return s.ctx && n(s.ctx[g], s.ctx[g] = y) && (!s.skip_bound && s.bound[g] && s.bound[g](y), w && Ne(t, g)), _; return c.ctx && n(c.ctx[g], c.ctx[g] = E) && (!c.skip_bound && c.bound[g] && c.bound[g](E), w && Ne(t, g)), _;
}) : [], s.update(), w = !0, U(s.before_update), s.fragment = l ? l(s.ctx) : !1, e.target) { }) : [], c.update(), w = !0, U(c.before_update), c.fragment = l ? l(c.ctx) : !1, e.target) {
if (e.hydrate) { if (e.hydrate) {
const g = xe(e.target); const g = xe(e.target);
s.fragment && s.fragment.l(g), g.forEach(k); c.fragment && c.fragment.l(g), g.forEach(x);
} else } else
s.fragment && s.fragment.c(); c.fragment && c.fragment.c();
e.intro && Ce(t.$$.fragment), Ae(t, e.target, e.anchor, e.customElement), x(); e.intro && Ce(t.$$.fragment), Ae(t, e.target, e.anchor, e.customElement), y();
} }
I(c); I(s);
} }
let X; let X;
typeof HTMLElement == "function" && (X = class extends HTMLElement { typeof HTMLElement == "function" && (X = class extends HTMLElement {
@ -213,11 +213,11 @@ function V(t) {
} }
function te(t, e, i) { function te(t, e, i) {
const l = t.slice(); const l = t.slice();
return l[12] = e[i], l; return l[13] = e[i], l;
} }
function ie(t, e, i) { function ie(t, e, i) {
const l = t.slice(); const l = t.slice();
return l[15] = e[i], l; return l[16] = e[i], l;
} }
function le(t) { function le(t) {
let e; let e;
@ -226,13 +226,13 @@ function le(t) {
e = m("link"), a(e, "rel", "stylesheet"), a(e, "href", t[4]); e = m("link"), a(e, "rel", "stylesheet"), a(e, "href", t[4]);
}, },
m(i, l) { m(i, l) {
p(i, e, l); k(i, e, l);
}, },
p(i, l) { p(i, l) {
l & 16 && a(e, "href", i[4]); l & 16 && a(e, "href", i[4]);
}, },
d(i) { d(i) {
i && k(e); i && x(e);
} }
}; };
} }
@ -242,32 +242,32 @@ function ne(t) {
r[o] = fe(te(t, n, o)); r[o] = fe(te(t, n, o));
return { return {
c() { c() {
e = m("div"), l && l.c(), i = M(); e = m("div"), l && l.c(), i = C();
for (let o = 0; o < r.length; o += 1) for (let o = 0; o < r.length; o += 1)
r[o].c(); r[o].c();
a(e, "id", "gancioEvents"), L(e, "dark", t[2] === "dark"), L(e, "light", t[2] === "light"), L(e, "sidebar", t[3] === "true"), L(e, "nosidebar", t[3] !== "true"); a(e, "id", "gancioEvents"), L(e, "dark", t[2] === "dark"), L(e, "light", t[2] === "light"), L(e, "sidebar", t[3] === "true"), L(e, "nosidebar", t[3] !== "true");
}, },
m(o, f) { m(o, f) {
p(o, e, f), l && l.m(e, null), u(e, i); k(o, e, f), l && l.m(e, null), u(e, i);
for (let c = 0; c < r.length; c += 1) for (let s = 0; s < r.length; s += 1)
r[c].m(e, null); r[s].m(e, null);
}, },
p(o, f) { p(o, f) {
if (o[1] && o[3] === "true" ? l ? l.p(o, f) : (l = re(o), l.c(), l.m(e, i)) : l && (l.d(1), l = null), f & 41) { if (o[1] && o[3] === "true" ? l ? l.p(o, f) : (l = re(o), l.c(), l.m(e, i)) : l && (l.d(1), l = null), f & 41) {
n = o[5]; n = o[5];
let c; let s;
for (c = 0; c < n.length; c += 1) { for (s = 0; s < n.length; s += 1) {
const s = te(o, n, c); const c = te(o, n, s);
r[c] ? r[c].p(s, f) : (r[c] = fe(s), r[c].c(), r[c].m(e, null)); r[s] ? r[s].p(c, f) : (r[s] = fe(c), r[s].c(), r[s].m(e, null));
} }
for (; c < r.length; c += 1) for (; s < r.length; s += 1)
r[c].d(1); r[s].d(1);
r.length = n.length; r.length = n.length;
} }
f & 4 && L(e, "dark", o[2] === "dark"), f & 4 && L(e, "light", o[2] === "light"), f & 8 && L(e, "sidebar", o[3] === "true"), f & 8 && L(e, "nosidebar", o[3] !== "true"); f & 4 && L(e, "dark", o[2] === "dark"), f & 4 && L(e, "light", o[2] === "light"), f & 8 && L(e, "sidebar", o[3] === "true"), f & 8 && L(e, "nosidebar", o[3] !== "true");
}, },
d(o) { d(o) {
o && k(e), l && l.d(), be(r, o); o && x(e), l && l.d(), be(r, o);
} }
}; };
} }
@ -275,23 +275,23 @@ function re(t) {
let e, i, l, n, r, o, f; let e, i, l, n, r, o, f;
return { return {
c() { c() {
e = m("a"), i = m("div"), l = m("div"), n = $(t[1]), r = M(), o = m("img"), a(l, "class", "title"), a(o, "id", "logo"), a(o, "alt", "logo"), H(o.src, f = t[0] + "/logo.png") || a(o, "src", f), a(i, "class", "content"), a(e, "href", t[0]), a(e, "target", "_blank"), a(e, "id", "header"); e = m("a"), i = m("div"), l = m("div"), n = z(t[1]), r = C(), o = m("img"), a(l, "class", "title"), a(o, "id", "logo"), a(o, "alt", "logo"), H(o.src, f = t[0] + "/logo.png") || a(o, "src", f), a(i, "class", "content"), a(e, "href", t[0]), a(e, "target", "_blank"), a(e, "id", "header");
}, },
m(c, s) { m(s, c) {
p(c, e, s), u(e, i), u(i, l), u(l, n), u(i, r), u(i, o); k(s, e, c), u(e, i), u(i, l), u(l, n), u(i, r), u(i, o);
}, },
p(c, s) { p(s, c) {
s & 2 && T(n, c[1]), s & 1 && !H(o.src, f = c[0] + "/logo.png") && a(o, "src", f), s & 1 && a(e, "href", c[0]); c & 2 && T(n, s[1]), c & 1 && !H(o.src, f = s[0] + "/logo.png") && a(o, "src", f), c & 1 && a(e, "href", s[0]);
}, },
d(c) { d(s) {
c && k(e); s && x(e);
} }
}; };
} }
function oe(t) { function oe(t) {
let e; let e;
function i(r, o) { function i(r, o) {
return r[12].media.length ? Le : Te; return r[13].media.length ? Le : Te;
} }
let l = i(t), n = l(t); let l = i(t), n = l(t);
return { return {
@ -299,13 +299,13 @@ function oe(t) {
e = m("div"), n.c(), a(e, "class", "img"); e = m("div"), n.c(), a(e, "class", "img");
}, },
m(r, o) { m(r, o) {
p(r, e, o), n.m(e, null); k(r, e, o), n.m(e, null);
}, },
p(r, o) { p(r, o) {
l === (l = i(r)) && n ? n.p(r, o) : (n.d(1), n = l(r), n && (n.c(), n.m(e, null))); l === (l = i(r)) && n ? n.p(r, o) : (n.d(1), n = l(r), n && (n.c(), n.m(e, null)));
}, },
d(r) { d(r) {
r && k(e), n.d(); r && x(e), n.d();
} }
}; };
} }
@ -313,16 +313,16 @@ function Te(t) {
let e, i, l; let e, i, l;
return { return {
c() { c() {
e = m("img"), a(e, "style", "aspect-ratio=1.7778;"), a(e, "alt", i = t[12].title), H(e.src, l = t[0] + "/fallbackimage.png") || a(e, "src", l), a(e, "loading", "lazy"); e = m("img"), a(e, "style", "aspect-ratio=1.7778;"), a(e, "alt", i = t[13].title), H(e.src, l = t[0] + "/fallbackimage.png") || a(e, "src", l), a(e, "loading", "lazy");
}, },
m(n, r) { m(n, r) {
p(n, e, r); k(n, e, r);
}, },
p(n, r) { p(n, r) {
r & 32 && i !== (i = n[12].title) && a(e, "alt", i), r & 1 && !H(e.src, l = n[0] + "/fallbackimage.png") && a(e, "src", l); r & 32 && i !== (i = n[13].title) && a(e, "alt", i), r & 1 && !H(e.src, l = n[0] + "/fallbackimage.png") && a(e, "src", l);
}, },
d(n) { d(n) {
n && k(e); n && x(e);
} }
}; };
} }
@ -330,38 +330,38 @@ function Le(t) {
let e, i, l, n; let e, i, l, n;
return { return {
c() { c() {
e = m("img"), a(e, "style", i = "object-position: " + ue(t[12]) + "; aspect-ratio=1.7778;"), a(e, "alt", l = t[12].media[0].name), H(e.src, n = t[0] + "/media/thumb/" + t[12].media[0].url) || a(e, "src", n), a(e, "loading", "lazy"); e = m("img"), a(e, "style", i = "object-position: " + ue(t[13]) + "; aspect-ratio=1.7778;"), a(e, "alt", l = t[13].media[0].name), H(e.src, n = t[0] + "/media/thumb/" + t[13].media[0].url) || a(e, "src", n), a(e, "loading", "lazy");
}, },
m(r, o) { m(r, o) {
p(r, e, o); k(r, e, o);
}, },
p(r, o) { p(r, o) {
o & 32 && i !== (i = "object-position: " + ue(r[12]) + "; aspect-ratio=1.7778;") && a(e, "style", i), o & 32 && l !== (l = r[12].media[0].name) && a(e, "alt", l), o & 33 && !H(e.src, n = r[0] + "/media/thumb/" + r[12].media[0].url) && a(e, "src", n); o & 32 && i !== (i = "object-position: " + ue(r[13]) + "; aspect-ratio=1.7778;") && a(e, "style", i), o & 32 && l !== (l = r[13].media[0].name) && a(e, "alt", l), o & 33 && !H(e.src, n = r[0] + "/media/thumb/" + r[13].media[0].url) && a(e, "src", n);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
function ae(t) { function ae(t) {
let e, i = t[12].place.address + "", l; let e, i = t[13].place.address + "", l;
return { return {
c() { c() {
e = m("span"), l = $(i), a(e, "class", "subtitle"); e = m("span"), l = z(i), a(e, "class", "subtitle");
}, },
m(n, r) { m(n, r) {
p(n, e, r), u(e, l); k(n, e, r), u(e, l);
}, },
p(n, r) { p(n, r) {
r & 32 && i !== (i = n[12].place.address + "") && T(l, i); r & 32 && i !== (i = n[13].place.address + "") && T(l, i);
}, },
d(n) { d(n) {
n && k(e); n && x(e);
} }
}; };
} }
function se(t) { function se(t) {
let e, i = t[12].tags, l = []; let e, i = t[13].tags, l = [];
for (let n = 0; n < i.length; n += 1) for (let n = 0; n < i.length; n += 1)
l[n] = ce(ie(t, i, n)); l[n] = ce(ie(t, i, n));
return { return {
@ -372,13 +372,13 @@ function se(t) {
a(e, "class", "tags"); a(e, "class", "tags");
}, },
m(n, r) { m(n, r) {
p(n, e, r); k(n, e, r);
for (let o = 0; o < l.length; o += 1) for (let o = 0; o < l.length; o += 1)
l[o].m(e, null); l[o].m(e, null);
}, },
p(n, r) { p(n, r) {
if (r & 32) { if (r & 32) {
i = n[12].tags; i = n[13].tags;
let o; let o;
for (o = 0; o < i.length; o += 1) { for (o = 0; o < i.length; o += 1) {
const f = ie(n, i, o); const f = ie(n, i, o);
@ -390,42 +390,41 @@ function se(t) {
} }
}, },
d(n) { d(n) {
n && k(e), be(l, n); n && x(e), be(l, n);
} }
}; };
} }
function ce(t) { function ce(t) {
let e, i, l = t[15] + "", n; let e, i, l = t[16] + "", n;
return { return {
c() { c() {
e = m("span"), i = $("#"), n = $(l), a(e, "class", "tag"); e = m("span"), i = z("#"), n = z(l), a(e, "class", "tag");
}, },
m(r, o) { m(r, o) {
p(r, e, o), u(e, i), u(e, n); k(r, e, o), u(e, i), u(e, n);
}, },
p(r, o) { p(r, o) {
o & 32 && l !== (l = r[15] + "") && T(n, l); o & 32 && l !== (l = r[16] + "") && T(n, l);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
function fe(t) { function fe(t) {
let e, i, l, n, r = V(t[12]) + "", o, f, c, s = t[12].title + "", w, g, _, A, y = t[12].place.name + "", d, z, h, v, C, q, E = t[3] !== "true" && oe(t), j = t[12].place.name !== "online" && ae(t), S = t[12].tags.length && se(t); let e, i, l, n, r = V(t[13]) + "", o, f, s, c = t[13].title + "", w, g, _, A, E = t[13].place.name + "", M, d, h, p, v, q, $ = t[3] !== "true" && oe(t), j = t[13].place.name !== "online" && ae(t), S = t[13].tags.length && se(t);
return { return {
c() { c() {
e = m("a"), E && E.c(), i = M(), l = m("div"), n = m("div"), o = $(r), f = M(), c = m("div"), w = $(s), g = M(), _ = m("span"), A = $('@"'), d = $(y), z = $(`" e = m("a"), $ && $.c(), i = C(), l = m("div"), n = m("div"), o = z(r), f = C(), s = m("div"), w = z(c), g = C(), _ = m("span"), A = z("@"), M = z(E), d = C(), j && j.c(), h = C(), S && S.c(), p = C(), a(n, "class", "subtitle"), a(s, "class", "title"), a(_, "class", "place"), a(l, "class", "content"), a(e, "href", v = t[0] + "/event/" + (t[13].slug || t[13].id)), a(e, "class", "event"), a(e, "title", q = t[13].title), a(e, "target", "_blank");
`), j && j.c(), h = M(), S && S.c(), v = M(), a(n, "class", "subtitle"), a(c, "class", "title"), a(_, "class", "place"), a(l, "class", "content"), a(e, "href", C = t[0] + "/event/" + (t[12].slug || t[12].id)), a(e, "class", "event"), a(e, "title", q = t[12].title), a(e, "target", "_blank");
}, },
m(b, N) { m(b, N) {
p(b, e, N), E && E.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, c), u(c, w), u(l, g), u(l, _), u(_, A), u(_, d), u(_, z), j && j.m(_, null), u(l, h), S && S.m(l, null), u(e, v); k(b, e, N), $ && $.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, s), u(s, w), u(l, g), u(l, _), u(_, A), u(_, M), u(_, d), j && j.m(_, null), u(l, h), S && S.m(l, null), u(e, p);
}, },
p(b, N) { p(b, N) {
b[3] !== "true" ? E ? E.p(b, N) : (E = oe(b), E.c(), E.m(e, i)) : E && (E.d(1), E = null), N & 32 && r !== (r = V(b[12]) + "") && T(o, r), N & 32 && s !== (s = b[12].title + "") && T(w, s), N & 32 && y !== (y = b[12].place.name + "") && T(d, y), b[12].place.name !== "online" ? j ? j.p(b, N) : (j = ae(b), j.c(), j.m(_, null)) : j && (j.d(1), j = null), b[12].tags.length ? S ? S.p(b, N) : (S = se(b), S.c(), S.m(l, null)) : S && (S.d(1), S = null), N & 33 && C !== (C = b[0] + "/event/" + (b[12].slug || b[12].id)) && a(e, "href", C), N & 32 && q !== (q = b[12].title) && a(e, "title", q); b[3] !== "true" ? $ ? $.p(b, N) : ($ = oe(b), $.c(), $.m(e, i)) : $ && ($.d(1), $ = null), N & 32 && r !== (r = V(b[13]) + "") && T(o, r), N & 32 && c !== (c = b[13].title + "") && T(w, c), N & 32 && E !== (E = b[13].place.name + "") && T(M, E), b[13].place.name !== "online" ? j ? j.p(b, N) : (j = ae(b), j.c(), j.m(_, null)) : j && (j.d(1), j = null), b[13].tags.length ? S ? S.p(b, N) : (S = se(b), S.c(), S.m(l, null)) : S && (S.d(1), S = null), N & 33 && v !== (v = b[0] + "/event/" + (b[13].slug || b[13].id)) && a(e, "href", v), N & 32 && q !== (q = b[13].title) && a(e, "title", q);
}, },
d(b) { d(b) {
b && k(e), E && E.d(), j && j.d(), S && S.d(); b && x(e), $ && $.d(), j && j.d(), S && S.d();
} }
}; };
} }
@ -433,10 +432,10 @@ function Ge(t) {
let e, i, l = t[4] && le(t), n = t[5].length && ne(t); let e, i, l = t[4] && le(t), n = t[5].length && ne(t);
return { return {
c() { c() {
l && l.c(), e = M(), n && n.c(), i = pe(), this.c = G; l && l.c(), e = C(), n && n.c(), i = pe(), this.c = G;
}, },
m(r, o) { m(r, o) {
l && l.m(r, o), p(r, e, o), n && n.m(r, o), p(r, i, o); l && l.m(r, o), k(r, e, o), n && n.m(r, o), k(r, i, o);
}, },
p(r, [o]) { p(r, [o]) {
r[4] ? l ? l.p(r, o) : (l = le(r), l.c(), l.m(e.parentNode, e)) : l && (l.d(1), l = null), r[5].length ? n ? n.p(r, o) : (n = ne(r), n.c(), n.m(i.parentNode, i)) : n && (n.d(1), n = null); r[4] ? l ? l.p(r, o) : (l = le(r), l.c(), l.m(e.parentNode, e)) : l && (l.d(1), l = null), r[5].length ? n ? n.p(r, o) : (n = ne(r), n.c(), n.m(i.parentNode, i)) : n && (n.d(1), n = null);
@ -444,7 +443,7 @@ function Ge(t) {
i: G, i: G,
o: G, o: G,
d(r) { d(r) {
l && l.d(r), r && k(e), n && n.d(r), r && k(i); l && l.d(r), r && x(e), n && n.d(r), r && x(i);
} }
}; };
} }
@ -456,34 +455,37 @@ function ue(t) {
return "center center"; return "center center";
} }
function He(t, e, i) { function He(t, e, i) {
let { baseurl: l = "" } = e, { title: n = "" } = e, { maxlength: r = !1 } = e, { tags: o = "" } = e, { places: f = "" } = e, { theme: c = "light" } = e, { show_recurrent: s = !1 } = e, { sidebar: w = "true" } = e, { external_style: g = "" } = e, _ = !1, A = []; let { baseurl: l = "" } = e, { title: n = "" } = e, { maxlength: r = !1 } = e, { collection: o = "" } = e, { tags: f = "" } = e, { places: s = "" } = e, { theme: c = "light" } = e, { show_recurrent: w = !1 } = e, { sidebar: g = "true" } = e, { external_style: _ = "" } = e, A = !1, E = [];
function y(d) { function M(d) {
if (!_) if (!A)
return; return;
const z = []; const h = [];
r && z.push(`max=${r}`), o && z.push(`tags=${o}`), f && z.push(`places=${f}`), z.push(`show_recurrent=${s ? "true" : "false"}`), fetch(`${l}/api/events?${z.join("&")}`).then((h) => h.json()).then((h) => { r && h.push(`max=${r}`);
i(5, A = h); let p = "/api/events";
}).catch((h) => { o ? p = `/api/collections/${o}` : (f && h.push(`tags=${f}`), s && h.push(`places=${s}`)), h.push(`show_recurrent=${w ? "true" : "false"}`), fetch(`${l}${p}?${h.join("&")}`).then((v) => v.json()).then((v) => {
console.error("Error loading Gancio API -> ", h); i(5, E = v.events || v);
}).catch((v) => {
console.error("Error loading Gancio API -> ", v);
}); });
} }
return ke(() => { return ke(() => {
_ = !0, y(); A = !0, M();
}), t.$$set = (d) => { }), t.$$set = (d) => {
"baseurl" in d && i(0, l = d.baseurl), "title" in d && i(1, n = d.title), "maxlength" in d && i(6, r = d.maxlength), "tags" in d && i(7, o = d.tags), "places" in d && i(8, f = d.places), "theme" in d && i(2, c = d.theme), "show_recurrent" in d && i(9, s = d.show_recurrent), "sidebar" in d && i(3, w = d.sidebar), "external_style" in d && i(4, g = d.external_style); "baseurl" in d && i(0, l = d.baseurl), "title" in d && i(1, n = d.title), "maxlength" in d && i(6, r = d.maxlength), "collection" in d && i(7, o = d.collection), "tags" in d && i(8, f = d.tags), "places" in d && i(9, s = d.places), "theme" in d && i(2, c = d.theme), "show_recurrent" in d && i(10, w = d.show_recurrent), "sidebar" in d && i(3, g = d.sidebar), "external_style" in d && i(4, _ = d.external_style);
}, t.$$.update = () => { }, t.$$.update = () => {
t.$$.dirty & 975 && y(); t.$$.dirty & 1999 && M();
}, [ }, [
l, l,
n, n,
c, c,
w,
g, g,
A, _,
E,
r, r,
o, o,
f, f,
s s,
w
]; ];
} }
class Re extends X { class Re extends X {
@ -508,21 +510,23 @@ class Re extends X {
baseurl: 0, baseurl: 0,
title: 1, title: 1,
maxlength: 6, maxlength: 6,
tags: 7, collection: 7,
places: 8, tags: 8,
places: 9,
theme: 2, theme: 2,
show_recurrent: 9, show_recurrent: 10,
sidebar: 3, sidebar: 3,
external_style: 4 external_style: 4
}, },
null null
), e && (e.target && p(e.target, this, e.anchor), e.props && (this.$set(e.props), x())); ), e && (e.target && k(e.target, this, e.anchor), e.props && (this.$set(e.props), y()));
} }
static get observedAttributes() { static get observedAttributes() {
return [ return [
"baseurl", "baseurl",
"title", "title",
"maxlength", "maxlength",
"collection",
"tags", "tags",
"places", "places",
"theme", "theme",
@ -535,72 +539,78 @@ class Re extends X {
return this.$$.ctx[0]; return this.$$.ctx[0];
} }
set baseurl(e) { set baseurl(e) {
this.$$set({ baseurl: e }), x(); this.$$set({ baseurl: e }), y();
} }
get title() { get title() {
return this.$$.ctx[1]; return this.$$.ctx[1];
} }
set title(e) { set title(e) {
this.$$set({ title: e }), x(); this.$$set({ title: e }), y();
} }
get maxlength() { get maxlength() {
return this.$$.ctx[6]; return this.$$.ctx[6];
} }
set maxlength(e) { set maxlength(e) {
this.$$set({ maxlength: e }), x(); this.$$set({ maxlength: e }), y();
} }
get tags() { get collection() {
return this.$$.ctx[7]; return this.$$.ctx[7];
} }
set tags(e) { set collection(e) {
this.$$set({ tags: e }), x(); this.$$set({ collection: e }), y();
} }
get places() { get tags() {
return this.$$.ctx[8]; return this.$$.ctx[8];
} }
set tags(e) {
this.$$set({ tags: e }), y();
}
get places() {
return this.$$.ctx[9];
}
set places(e) { set places(e) {
this.$$set({ places: e }), x(); this.$$set({ places: e }), y();
} }
get theme() { get theme() {
return this.$$.ctx[2]; return this.$$.ctx[2];
} }
set theme(e) { set theme(e) {
this.$$set({ theme: e }), x(); this.$$set({ theme: e }), y();
} }
get show_recurrent() { get show_recurrent() {
return this.$$.ctx[9]; return this.$$.ctx[10];
} }
set show_recurrent(e) { set show_recurrent(e) {
this.$$set({ show_recurrent: e }), x(); this.$$set({ show_recurrent: e }), y();
} }
get sidebar() { get sidebar() {
return this.$$.ctx[3]; return this.$$.ctx[3];
} }
set sidebar(e) { set sidebar(e) {
this.$$set({ sidebar: e }), x(); this.$$set({ sidebar: e }), y();
} }
get external_style() { get external_style() {
return this.$$.ctx[4]; return this.$$.ctx[4];
} }
set external_style(e) { set external_style(e) {
this.$$set({ external_style: e }), x(); this.$$set({ external_style: e }), y();
} }
} }
customElements.define("gancio-events", Re); customElements.define("gancio-events", Re);
function de(t) { function de(t) {
let e, i, l, n, r = t[1].title + "", o, f, c, s = V(t[1]) + "", w, g, _, A, y = t[1].place.name + "", d, z, h = t[1].media.length && he(t); let e, i, l, n, r = t[1].title + "", o, f, s, c = V(t[1]) + "", w, g, _, A, E = t[1].place.name + "", M, d, h = t[1].media.length && he(t);
return { return {
c() { c() {
e = m("a"), h && h.c(), i = M(), l = m("div"), n = m("strong"), o = $(r), f = M(), c = m("div"), w = $(s), g = M(), _ = m("div"), A = $("@"), d = $(y), a(_, "class", "place"), a(l, "class", "container"), a(e, "href", z = t[0] + "/event/" + (t[1].slug || t[1].id)), a(e, "class", "card"), a(e, "target", "_blank"); e = m("a"), h && h.c(), i = C(), l = m("div"), n = m("strong"), o = z(r), f = C(), s = m("div"), w = z(c), g = C(), _ = m("div"), A = z("@"), M = z(E), a(_, "class", "place"), a(l, "class", "container"), a(e, "href", d = t[0] + "/event/" + (t[1].slug || t[1].id)), a(e, "class", "card"), a(e, "target", "_blank");
}, },
m(v, C) { m(p, v) {
p(v, e, C), h && h.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, c), u(c, w), u(l, g), u(l, _), u(_, A), u(_, d); k(p, e, v), h && h.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, s), u(s, w), u(l, g), u(l, _), u(_, A), u(_, M);
}, },
p(v, C) { p(p, v) {
v[1].media.length ? h ? h.p(v, C) : (h = he(v), h.c(), h.m(e, i)) : h && (h.d(1), h = null), C & 2 && r !== (r = v[1].title + "") && T(o, r), C & 2 && s !== (s = V(v[1]) + "") && T(w, s), C & 2 && y !== (y = v[1].place.name + "") && T(d, y), C & 3 && z !== (z = v[0] + "/event/" + (v[1].slug || v[1].id)) && a(e, "href", z); p[1].media.length ? h ? h.p(p, v) : (h = he(p), h.c(), h.m(e, i)) : h && (h.d(1), h = null), v & 2 && r !== (r = p[1].title + "") && T(o, r), v & 2 && c !== (c = V(p[1]) + "") && T(w, c), v & 2 && E !== (E = p[1].place.name + "") && T(M, E), v & 3 && d !== (d = p[0] + "/event/" + (p[1].slug || p[1].id)) && a(e, "href", d);
}, },
d(v) { d(p) {
v && k(e), h && h.d(); p && x(e), h && h.d();
} }
}; };
} }
@ -611,13 +621,13 @@ function he(t) {
e = m("img"), H(e.src, i = t[2](t[1])) || a(e, "src", i), a(e, "alt", l = t[1].media[0].name), a(e, "style", n = "object-position: " + me(t[1]) + "; aspect-ratio=1.7778;"); e = m("img"), H(e.src, i = t[2](t[1])) || a(e, "src", i), a(e, "alt", l = t[1].media[0].name), a(e, "style", n = "object-position: " + me(t[1]) + "; aspect-ratio=1.7778;");
}, },
m(r, o) { m(r, o) {
p(r, e, o); k(r, e, o);
}, },
p(r, o) { p(r, o) {
o & 2 && !H(e.src, i = r[2](r[1])) && a(e, "src", i), o & 2 && l !== (l = r[1].media[0].name) && a(e, "alt", l), o & 2 && n !== (n = "object-position: " + me(r[1]) + "; aspect-ratio=1.7778;") && a(e, "style", n); o & 2 && !H(e.src, i = r[2](r[1])) && a(e, "src", i), o & 2 && l !== (l = r[1].media[0].name) && a(e, "alt", l), o & 2 && n !== (n = "object-position: " + me(r[1]) + "; aspect-ratio=1.7778;") && a(e, "style", n);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
@ -628,7 +638,7 @@ function Ie(t) {
i && i.c(), e = pe(), this.c = G; i && i.c(), e = pe(), this.c = G;
}, },
m(l, n) { m(l, n) {
i && i.m(l, n), p(l, e, n); i && i.m(l, n), k(l, e, n);
}, },
p(l, [n]) { p(l, [n]) {
l[1] ? i ? i.p(l, n) : (i = de(l), i.c(), i.m(e.parentNode, e)) : i && (i.d(1), i = null); l[1] ? i ? i.p(l, n) : (i = de(l), i.c(), i.m(e.parentNode, e)) : i && (i.d(1), i = null);
@ -636,7 +646,7 @@ function Ie(t) {
i: G, i: G,
o: G, o: G,
d(l) { d(l) {
i && i.d(l), l && k(e); i && i.d(l), l && x(e);
} }
}; };
} }
@ -649,20 +659,20 @@ function me(t) {
} }
function Oe(t, e, i) { function Oe(t, e, i) {
let { baseurl: l = "https://demo.gancio.org" } = e, { id: n } = e, r = !1, o; let { baseurl: l = "https://demo.gancio.org" } = e, { id: n } = e, r = !1, o;
function f(s, w) { function f(c, w) {
r && fetch(`${w}/api/event/detail/${s}`).then((g) => g.json()).then((g) => i(1, o = g)); r && fetch(`${w}/api/event/detail/${c}`).then((g) => g.json()).then((g) => i(1, o = g));
} }
ke(() => { ke(() => {
r = !0, f(n, l); r = !0, f(n, l);
}); });
function c(s) { function s(c) {
return `${l}/media/thumb/${s.media[0].url}`; return `${l}/media/thumb/${c.media[0].url}`;
} }
return t.$$set = (s) => { return t.$$set = (c) => {
"baseurl" in s && i(0, l = s.baseurl), "id" in s && i(3, n = s.id); "baseurl" in c && i(0, l = c.baseurl), "id" in c && i(3, n = c.id);
}, t.$$.update = () => { }, t.$$.update = () => {
t.$$.dirty & 9 && f(n, l); t.$$.dirty & 9 && f(n, l);
}, [l, o, c, n]; }, [l, o, s, n];
} }
class Ue extends X { class Ue extends X {
constructor(e) { constructor(e) {
@ -679,7 +689,7 @@ class Ue extends X {
_e, _e,
{ baseurl: 0, id: 3 }, { baseurl: 0, id: 3 },
null null
), e && (e.target && p(e.target, this, e.anchor), e.props && (this.$set(e.props), x())); ), e && (e.target && k(e.target, this, e.anchor), e.props && (this.$set(e.props), y()));
} }
static get observedAttributes() { static get observedAttributes() {
return ["baseurl", "id"]; return ["baseurl", "id"];
@ -688,13 +698,13 @@ class Ue extends X {
return this.$$.ctx[0]; return this.$$.ctx[0];
} }
set baseurl(e) { set baseurl(e) {
this.$$set({ baseurl: e }), x(); this.$$set({ baseurl: e }), y();
} }
get id() { get id() {
return this.$$.ctx[3]; return this.$$.ctx[3];
} }
set id(e) { set id(e) {
this.$$set({ id: e }), x(); this.$$set({ id: e }), y();
} }
} }
customElements.define("gancio-event", Ue); customElements.define("gancio-event", Ue);

View file

@ -207,6 +207,49 @@ describe('Events', () => {
}) })
test('should not allow start_datetime greater than end_datetime', async () => {
const event = {
title: ' test title 5',
place_id: places[0],
start_datetime: dayjs().unix() + 1000,
end_datetime: dayjs().unix(),
}
const response = await request(app).post('/api/event')
.send(event)
.expect(400)
expect(response.text).toBe('start datetime is greater than end datetime')
})
test('should not allow start_datetime greater than 3000', async () => {
const event = {
title: ' test title 5',
start_datetime: dayjs().set('year', 4000).unix(),
place_id: places[0],
}
const response = await request(app).post('/api/event')
.send(event)
.expect(400)
expect(response.text).toBe('are you sure?')
})
test('should validate start_datime', async () => {
const event = {
title: ' test title 5',
start_datetime: "antani",
place_id: places[0],
}
const response = await request(app).post('/api/event')
.send(event)
.expect(400)
})
test('should trim tags and title', async () => { test('should trim tags and title', async () => {
const event = { const event = {
title: ' test title 4 ', title: ' test title 4 ',
@ -384,7 +427,7 @@ describe('Collection', () => {
}) })
test('shoud get collection\'s filters using withFilters parameter', async () => { test('shoud get collection\'s filters using withFilters parameter', async () => {
const response = await request(app) let response = await request(app)
.get('/api/collections?withFilters=true') .get('/api/collections?withFilters=true')
.expect(200) .expect(200)
@ -393,6 +436,18 @@ describe('Collection', () => {
expect(response.body[0].filters.length).toBe(1) expect(response.body[0].filters.length).toBe(1)
expect(response.body[0].filters[0].tags.length).toBe(1) expect(response.body[0].filters[0].tags.length).toBe(1)
expect(response.body[0].filters[0].tags[0]).toBe('test') expect(response.body[0].filters[0].tags[0]).toBe('test')
response = await request(app)
.get('/api/collections')
.expect(200)
expect(response.body[0].filters).toBeUndefined()
response = await request(app)
.get('/api/collections?withFilters=false')
.expect(200)
expect(response.body[0].filters).toBeUndefined()
}) })
test('should get collection events', async () => { test('should get collection events', async () => {

View file

@ -50,13 +50,14 @@ describe('Recurrent events', () => {
start_datetime: DateTime.local(2023, 3, 27, 8).toUnixInteger(), start_datetime: DateTime.local(2023, 3, 27, 8).toUnixInteger(),
}) })
// 27 March 2023 08:00 -> 1w -> 3 April 2023 08:00 // 27 March 2023 08:00 -> 1w
let ev = await eventController._createRecurrentOccurrence(ret) let ev = await eventController._createRecurrentOccurrence(ret)
expect(ev.start_datetime).toBe(DateTime.local(2023, 4, 3, 8).toUnixInteger()) expect(ev.start_datetime).toBeGreaterThan(DateTime.local().toUnixInteger())
expect(DateTime.fromSeconds(ev.start_datetime).hour).toBe(8)
// 3 April 2023 08:00 -> 1w -> 10 April 2023 08:00 // 3 April 2023 08:00 -> 1w -> 10 April 2023 08:00
ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false) // ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false)
expect(ev.start_datetime).toBe(DateTime.local(2023, 4, 10, 8).toUnixInteger()) // expect(ev.start_datetime).
// weekly test // weekly test
// data di inizio prima di oggi // data di inizio prima di oggi
@ -94,27 +95,6 @@ describe('Recurrent events', () => {
}) })
test('shoud create a 2 week occurrence in future when start date time is in past', async () => {
const eventController = require('../server/api/controller/event')
const { Event } = require('../server/api/models/models')
// each week starting from past
let ret = await Event.create({
title: 'each 2 weeks starting from past',
is_visible: true,
recurrent: { frequency: '2w' },
start_datetime: DateTime.local(2023, 3, 27, 8).toUnixInteger(),
})
// 27 March 2023 08:00 -> 2w -> 10 April 2023 08:00
let ev = await eventController._createRecurrentOccurrence(ret)
expect(ev.start_datetime).toBe(DateTime.local(2023, 4, 10, 8).toUnixInteger())
// 10 April 2023 08:00 -> 2w -> 24 April 2023 08:00
ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false)
expect(ev.start_datetime).toBe(DateTime.local(2023, 4, 24, 8).toUnixInteger())
})
test('shoud create a 2 week occurrence in future when start date time is in future', async () => { test('shoud create a 2 week occurrence in future when start date time is in future', async () => {
const eventController = require('../server/api/controller/event') const eventController = require('../server/api/controller/event')
const { Event } = require('../server/api/models/models') const { Event } = require('../server/api/models/models')
@ -163,22 +143,60 @@ describe('Recurrent events', () => {
const eventController = require('../server/api/controller/event') const eventController = require('../server/api/controller/event')
const { Event } = require('../server/api/models/models') const { Event } = require('../server/api/models/models')
// each week starting from past // each week
let ret = await Event.create({ let ret = await Event.create({
title: 'each last monday starting from past', title: 'each last monday starting',
is_visible: true, is_visible: true,
recurrent: { frequency: '1m', type: -1 }, recurrent: { frequency: '1m', type: -1 },
start_datetime: DateTime.local(2023, 3, 27, 8).toUnixInteger(), start_datetime: DateTime.local(2033, 3, 27, 8).toUnixInteger(),
}) })
// 27 March 2033 08:00 -> 1m -> 24 April 2033 08:00
ev = await eventController._createRecurrentOccurrence(ret) ev = await eventController._createRecurrentOccurrence(ret)
expect(ev.start_datetime).toBe(DateTime.local(2023, 4, 24, 8).toUnixInteger()) expect(ev.start_datetime).toBe(DateTime.local(2033, 3, 27, 8).toUnixInteger())
// 27 March 2033 08:00 -> 1m -> 24 April 2033 08:00
ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false)
expect(ev.start_datetime).toBe(DateTime.local(2033, 4, 24, 8).toUnixInteger())
// 24 April 2033 08:00 -> 1m -> 29 May 2033 08:00 // 24 April 2033 08:00 -> 1m -> 29 May 2033 08:00
ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false) ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false)
expect(ev.start_datetime).toBe(DateTime.local(2023, 5, 29, 8).toUnixInteger()) expect(ev.start_datetime).toBe(DateTime.local(2033, 5, 29, 8).toUnixInteger())
})
test('shoud create an occurrence each second tuesday', async () => {
const eventController = require('../server/api/controller/event')
const { Event } = require('../server/api/models/models')
// each week starting from past
let ret = await Event.create({
title: 'each second tuesday',
is_visible: true,
recurrent: { frequency: '1m', type: 2 },
start_datetime: DateTime.local(2033, 2, 8, 8).toUnixInteger(),
})
ev = await eventController._createRecurrentOccurrence(ret)
expect(ev.start_datetime).toBe(DateTime.local(2033, 2, 8, 8).toUnixInteger())
ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false)
expect(ev.start_datetime).toBe(DateTime.local(2033, 3, 8, 8).toUnixInteger())
// 8 March 2033 08:00 -> 1m -> 12 April 2033 08:00
ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false)
expect(ev.start_datetime).toBe(DateTime.local(2033, 4, 12, 8).toUnixInteger())
// 12 Apr 2033 08:00 -> 1m -> 10 May 2033 08:00
ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false)
expect(ev.start_datetime).toBe(DateTime.local(2033, 5, 10, 8).toUnixInteger())
// 10 May 2033 08:00 -> 1m -> 9 June 2033 08:00
ev = await eventController._createRecurrentOccurrence(ret, DateTime.fromSeconds(ev.start_datetime+1), false)
expect(ev.start_datetime).toBe(DateTime.local(2033, 6, 14, 8).toUnixInteger())
}) })
}) })

View file

@ -9,10 +9,10 @@ rss(version='2.0' xmlns:atom="http://www.w3.org/2005/Atom")
item item
if (event.media && event.media.length) if (event.media && event.media.length)
<enclosure url="#{settings.baseurl}/media/#{event.media[0].url}" type='image/jpeg' length="#{event.media[0].size||1}"></enclosure> <enclosure url="#{settings.baseurl}/media/#{event.media[0].url}" type='image/jpeg' length="#{event.media[0].size||1}"></enclosure>
title [#{unixFormat(event.start_datetime,"yy-MM-dd")}] #{event.title} @ #{event.place.name} title [#{unixFormat(event.start_datetime,"yyyy-MM-dd")}] #{event.title} @ #{event.place.name}
link #{settings.baseurl}/event/#{event.slug || event.id} link #{settings.baseurl}/event/#{event.slug || event.id}
each tag in event.tags each tag in event.tags
category #{tag.tag} category #{tag.tag || tag}
description description
| <![CDATA[ | <![CDATA[
| <h4>#{event.title}</h4> | <h4>#{event.title}</h4>

View file

@ -1,12 +1,12 @@
const minifyTheme = require('minify-css-string').default const minifyTheme = require('minify-css-string').default
import { ca, de, en, es, eu, fr, gl, it, nb, nl, pl, pt, sk, ru, zhHans } from 'vuetify/es5/locale' import { ca, cs, de, en, es, eu, fr, gl, it, nb, nl, pl, pt, sk, ru, zhHans } from 'vuetify/es5/locale'
export default ({ res, nuxtState }) => { export default ({ res, nuxtState }) => {
const settings = process.server ? res.locals.settings : nuxtState.state.settings const settings = process.server ? (res.locals.settings || {}) : nuxtState.state.settings || {}
return { return {
lang: { locales: { ca, de, en, es, eu, fr, gl, it, nb, nl, pl, pt, sk, ru, zhHans } }, lang: { locales: { ca, cs, de, en, es, eu, fr, gl, it, nb, nl, pl, pt, sk, ru, zhHans } },
treeShake: true, treeShake: true,
theme: { theme: {
options: { options: {

View file

@ -6,6 +6,7 @@
export let baseurl = '' export let baseurl = ''
export let title = '' export let title = ''
export let maxlength = false export let maxlength = false
export let collection = ''
export let tags = '' export let tags = ''
export let places = '' export let places = ''
export let theme = 'light' export let theme = 'light'
@ -24,6 +25,10 @@
params.push(`max=${maxlength}`) params.push(`max=${maxlength}`)
} }
let api = '/api/events'
if (collection) {
api = `/api/collections/${collection}`
} else {
if (tags) { if (tags) {
params.push(`tags=${tags}`) params.push(`tags=${tags}`)
} }
@ -31,13 +36,13 @@
if (places) { if (places) {
params.push(`places=${places}`) params.push(`places=${places}`)
} }
}
params.push(`show_recurrent=${show_recurrent ? 'true' : 'false'}`) params.push(`show_recurrent=${show_recurrent ? 'true' : 'false'}`)
fetch(`${baseurl}/api/events?${params.join('&')}`) fetch(`${baseurl}${api}?${params.join('&')}`)
.then((res) => res.json()) .then((res) => res.json())
.then((e) => { .then((e) => {
events = e events = e.events || e
}) })
.catch((e) => { .catch((e) => {
console.error('Error loading Gancio API -> ', e) console.error('Error loading Gancio API -> ', e)
@ -57,7 +62,7 @@
update() update()
}) })
$: update( $: update(
maxlength && title && places && tags && theme && show_recurrent && sidebar && baseurl maxlength && title && places && tags && theme && show_recurrent && sidebar && baseurl && collection
) )
</script> </script>

View file

@ -25,10 +25,10 @@ function ye(t) {
function u(t, e) { function u(t, e) {
t.appendChild(e); t.appendChild(e);
} }
function p(t, e, i) { function k(t, e, i) {
t.insertBefore(e, i || null); t.insertBefore(e, i || null);
} }
function k(t) { function x(t) {
t.parentNode.removeChild(t); t.parentNode.removeChild(t);
} }
function be(t, e) { function be(t, e) {
@ -38,14 +38,14 @@ function be(t, e) {
function m(t) { function m(t) {
return document.createElement(t); return document.createElement(t);
} }
function $(t) { function z(t) {
return document.createTextNode(t); return document.createTextNode(t);
} }
function M() { function C() {
return $(" "); return z(" ");
} }
function pe() { function pe() {
return $(""); return z("");
} }
function a(t, e, i) { function a(t, e, i) {
i == null ? t.removeAttribute(e) : t.getAttribute(e) !== i && t.setAttribute(e, i); i == null ? t.removeAttribute(e) : t.getAttribute(e) !== i && t.setAttribute(e, i);
@ -69,25 +69,25 @@ let O;
function I(t) { function I(t) {
O = t; O = t;
} }
function $e() { function Ee() {
if (!O) if (!O)
throw new Error("Function called outside component initialization"); throw new Error("Function called outside component initialization");
return O; return O;
} }
function ke(t) { function ke(t) {
$e().$$.on_mount.push(t); Ee().$$.on_mount.push(t);
} }
const R = [], Z = [], P = [], ee = [], Ee = Promise.resolve(); const R = [], Z = [], P = [], ee = [], $e = Promise.resolve();
let K = !1; let K = !1;
function je() { function je() {
K || (K = !0, Ee.then(x)); K || (K = !0, $e.then(y));
} }
function Q(t) { function Q(t) {
P.push(t); P.push(t);
} }
const J = /* @__PURE__ */ new Set(); const J = /* @__PURE__ */ new Set();
let D = 0; let D = 0;
function x() { function y() {
const t = O; const t = O;
do { do {
for (; D < R.length; ) { for (; D < R.length; ) {
@ -120,8 +120,8 @@ function Ce(t, e) {
function Ae(t, e, i, l) { function Ae(t, e, i, l) {
const { fragment: n, on_mount: r, on_destroy: o, after_update: f } = t.$$; const { fragment: n, on_mount: r, on_destroy: o, after_update: f } = t.$$;
n && n.m(e, i), l || Q(() => { n && n.m(e, i), l || Q(() => {
const c = r.map(W).filter(ge); const s = r.map(W).filter(ge);
o ? o.push(...c) : U(c), t.$$.on_mount = []; o ? o.push(...s) : U(s), t.$$.on_mount = [];
}), f.forEach(Q); }), f.forEach(Q);
} }
function Me(t, e) { function Me(t, e) {
@ -132,9 +132,9 @@ function Ne(t, e) {
t.$$.dirty[0] === -1 && (R.push(t), je(), t.$$.dirty.fill(0)), t.$$.dirty[e / 31 | 0] |= 1 << e % 31; t.$$.dirty[0] === -1 && (R.push(t), je(), t.$$.dirty.fill(0)), t.$$.dirty[e / 31 | 0] |= 1 << e % 31;
} }
function we(t, e, i, l, n, r, o, f = [-1]) { function we(t, e, i, l, n, r, o, f = [-1]) {
const c = O; const s = O;
I(t); I(t);
const s = t.$$ = { const c = t.$$ = {
fragment: null, fragment: null,
ctx: null, ctx: null,
props: r, props: r,
@ -146,26 +146,26 @@ function we(t, e, i, l, n, r, o, f = [-1]) {
on_disconnect: [], on_disconnect: [],
before_update: [], before_update: [],
after_update: [], after_update: [],
context: new Map(e.context || (c ? c.$$.context : [])), context: new Map(e.context || (s ? s.$$.context : [])),
callbacks: Y(), callbacks: Y(),
dirty: f, dirty: f,
skip_bound: !1, skip_bound: !1,
root: e.target || c.$$.root root: e.target || s.$$.root
}; };
o && o(s.root); o && o(c.root);
let w = !1; let w = !1;
if (s.ctx = i ? i(t, e.props || {}, (g, _, ...A) => { if (c.ctx = i ? i(t, e.props || {}, (g, _, ...A) => {
const y = A.length ? A[0] : _; const E = A.length ? A[0] : _;
return s.ctx && n(s.ctx[g], s.ctx[g] = y) && (!s.skip_bound && s.bound[g] && s.bound[g](y), w && Ne(t, g)), _; return c.ctx && n(c.ctx[g], c.ctx[g] = E) && (!c.skip_bound && c.bound[g] && c.bound[g](E), w && Ne(t, g)), _;
}) : [], s.update(), w = !0, U(s.before_update), s.fragment = l ? l(s.ctx) : !1, e.target) { }) : [], c.update(), w = !0, U(c.before_update), c.fragment = l ? l(c.ctx) : !1, e.target) {
if (e.hydrate) { if (e.hydrate) {
const g = xe(e.target); const g = xe(e.target);
s.fragment && s.fragment.l(g), g.forEach(k); c.fragment && c.fragment.l(g), g.forEach(x);
} else } else
s.fragment && s.fragment.c(); c.fragment && c.fragment.c();
e.intro && Ce(t.$$.fragment), Ae(t, e.target, e.anchor, e.customElement), x(); e.intro && Ce(t.$$.fragment), Ae(t, e.target, e.anchor, e.customElement), y();
} }
I(c); I(s);
} }
let X; let X;
typeof HTMLElement == "function" && (X = class extends HTMLElement { typeof HTMLElement == "function" && (X = class extends HTMLElement {
@ -213,11 +213,11 @@ function V(t) {
} }
function te(t, e, i) { function te(t, e, i) {
const l = t.slice(); const l = t.slice();
return l[12] = e[i], l; return l[13] = e[i], l;
} }
function ie(t, e, i) { function ie(t, e, i) {
const l = t.slice(); const l = t.slice();
return l[15] = e[i], l; return l[16] = e[i], l;
} }
function le(t) { function le(t) {
let e; let e;
@ -226,13 +226,13 @@ function le(t) {
e = m("link"), a(e, "rel", "stylesheet"), a(e, "href", t[4]); e = m("link"), a(e, "rel", "stylesheet"), a(e, "href", t[4]);
}, },
m(i, l) { m(i, l) {
p(i, e, l); k(i, e, l);
}, },
p(i, l) { p(i, l) {
l & 16 && a(e, "href", i[4]); l & 16 && a(e, "href", i[4]);
}, },
d(i) { d(i) {
i && k(e); i && x(e);
} }
}; };
} }
@ -242,32 +242,32 @@ function ne(t) {
r[o] = fe(te(t, n, o)); r[o] = fe(te(t, n, o));
return { return {
c() { c() {
e = m("div"), l && l.c(), i = M(); e = m("div"), l && l.c(), i = C();
for (let o = 0; o < r.length; o += 1) for (let o = 0; o < r.length; o += 1)
r[o].c(); r[o].c();
a(e, "id", "gancioEvents"), L(e, "dark", t[2] === "dark"), L(e, "light", t[2] === "light"), L(e, "sidebar", t[3] === "true"), L(e, "nosidebar", t[3] !== "true"); a(e, "id", "gancioEvents"), L(e, "dark", t[2] === "dark"), L(e, "light", t[2] === "light"), L(e, "sidebar", t[3] === "true"), L(e, "nosidebar", t[3] !== "true");
}, },
m(o, f) { m(o, f) {
p(o, e, f), l && l.m(e, null), u(e, i); k(o, e, f), l && l.m(e, null), u(e, i);
for (let c = 0; c < r.length; c += 1) for (let s = 0; s < r.length; s += 1)
r[c].m(e, null); r[s].m(e, null);
}, },
p(o, f) { p(o, f) {
if (o[1] && o[3] === "true" ? l ? l.p(o, f) : (l = re(o), l.c(), l.m(e, i)) : l && (l.d(1), l = null), f & 41) { if (o[1] && o[3] === "true" ? l ? l.p(o, f) : (l = re(o), l.c(), l.m(e, i)) : l && (l.d(1), l = null), f & 41) {
n = o[5]; n = o[5];
let c; let s;
for (c = 0; c < n.length; c += 1) { for (s = 0; s < n.length; s += 1) {
const s = te(o, n, c); const c = te(o, n, s);
r[c] ? r[c].p(s, f) : (r[c] = fe(s), r[c].c(), r[c].m(e, null)); r[s] ? r[s].p(c, f) : (r[s] = fe(c), r[s].c(), r[s].m(e, null));
} }
for (; c < r.length; c += 1) for (; s < r.length; s += 1)
r[c].d(1); r[s].d(1);
r.length = n.length; r.length = n.length;
} }
f & 4 && L(e, "dark", o[2] === "dark"), f & 4 && L(e, "light", o[2] === "light"), f & 8 && L(e, "sidebar", o[3] === "true"), f & 8 && L(e, "nosidebar", o[3] !== "true"); f & 4 && L(e, "dark", o[2] === "dark"), f & 4 && L(e, "light", o[2] === "light"), f & 8 && L(e, "sidebar", o[3] === "true"), f & 8 && L(e, "nosidebar", o[3] !== "true");
}, },
d(o) { d(o) {
o && k(e), l && l.d(), be(r, o); o && x(e), l && l.d(), be(r, o);
} }
}; };
} }
@ -275,23 +275,23 @@ function re(t) {
let e, i, l, n, r, o, f; let e, i, l, n, r, o, f;
return { return {
c() { c() {
e = m("a"), i = m("div"), l = m("div"), n = $(t[1]), r = M(), o = m("img"), a(l, "class", "title"), a(o, "id", "logo"), a(o, "alt", "logo"), H(o.src, f = t[0] + "/logo.png") || a(o, "src", f), a(i, "class", "content"), a(e, "href", t[0]), a(e, "target", "_blank"), a(e, "id", "header"); e = m("a"), i = m("div"), l = m("div"), n = z(t[1]), r = C(), o = m("img"), a(l, "class", "title"), a(o, "id", "logo"), a(o, "alt", "logo"), H(o.src, f = t[0] + "/logo.png") || a(o, "src", f), a(i, "class", "content"), a(e, "href", t[0]), a(e, "target", "_blank"), a(e, "id", "header");
}, },
m(c, s) { m(s, c) {
p(c, e, s), u(e, i), u(i, l), u(l, n), u(i, r), u(i, o); k(s, e, c), u(e, i), u(i, l), u(l, n), u(i, r), u(i, o);
}, },
p(c, s) { p(s, c) {
s & 2 && T(n, c[1]), s & 1 && !H(o.src, f = c[0] + "/logo.png") && a(o, "src", f), s & 1 && a(e, "href", c[0]); c & 2 && T(n, s[1]), c & 1 && !H(o.src, f = s[0] + "/logo.png") && a(o, "src", f), c & 1 && a(e, "href", s[0]);
}, },
d(c) { d(s) {
c && k(e); s && x(e);
} }
}; };
} }
function oe(t) { function oe(t) {
let e; let e;
function i(r, o) { function i(r, o) {
return r[12].media.length ? Le : Te; return r[13].media.length ? Le : Te;
} }
let l = i(t), n = l(t); let l = i(t), n = l(t);
return { return {
@ -299,13 +299,13 @@ function oe(t) {
e = m("div"), n.c(), a(e, "class", "img"); e = m("div"), n.c(), a(e, "class", "img");
}, },
m(r, o) { m(r, o) {
p(r, e, o), n.m(e, null); k(r, e, o), n.m(e, null);
}, },
p(r, o) { p(r, o) {
l === (l = i(r)) && n ? n.p(r, o) : (n.d(1), n = l(r), n && (n.c(), n.m(e, null))); l === (l = i(r)) && n ? n.p(r, o) : (n.d(1), n = l(r), n && (n.c(), n.m(e, null)));
}, },
d(r) { d(r) {
r && k(e), n.d(); r && x(e), n.d();
} }
}; };
} }
@ -313,16 +313,16 @@ function Te(t) {
let e, i, l; let e, i, l;
return { return {
c() { c() {
e = m("img"), a(e, "style", "aspect-ratio=1.7778;"), a(e, "alt", i = t[12].title), H(e.src, l = t[0] + "/fallbackimage.png") || a(e, "src", l), a(e, "loading", "lazy"); e = m("img"), a(e, "style", "aspect-ratio=1.7778;"), a(e, "alt", i = t[13].title), H(e.src, l = t[0] + "/fallbackimage.png") || a(e, "src", l), a(e, "loading", "lazy");
}, },
m(n, r) { m(n, r) {
p(n, e, r); k(n, e, r);
}, },
p(n, r) { p(n, r) {
r & 32 && i !== (i = n[12].title) && a(e, "alt", i), r & 1 && !H(e.src, l = n[0] + "/fallbackimage.png") && a(e, "src", l); r & 32 && i !== (i = n[13].title) && a(e, "alt", i), r & 1 && !H(e.src, l = n[0] + "/fallbackimage.png") && a(e, "src", l);
}, },
d(n) { d(n) {
n && k(e); n && x(e);
} }
}; };
} }
@ -330,38 +330,38 @@ function Le(t) {
let e, i, l, n; let e, i, l, n;
return { return {
c() { c() {
e = m("img"), a(e, "style", i = "object-position: " + ue(t[12]) + "; aspect-ratio=1.7778;"), a(e, "alt", l = t[12].media[0].name), H(e.src, n = t[0] + "/media/thumb/" + t[12].media[0].url) || a(e, "src", n), a(e, "loading", "lazy"); e = m("img"), a(e, "style", i = "object-position: " + ue(t[13]) + "; aspect-ratio=1.7778;"), a(e, "alt", l = t[13].media[0].name), H(e.src, n = t[0] + "/media/thumb/" + t[13].media[0].url) || a(e, "src", n), a(e, "loading", "lazy");
}, },
m(r, o) { m(r, o) {
p(r, e, o); k(r, e, o);
}, },
p(r, o) { p(r, o) {
o & 32 && i !== (i = "object-position: " + ue(r[12]) + "; aspect-ratio=1.7778;") && a(e, "style", i), o & 32 && l !== (l = r[12].media[0].name) && a(e, "alt", l), o & 33 && !H(e.src, n = r[0] + "/media/thumb/" + r[12].media[0].url) && a(e, "src", n); o & 32 && i !== (i = "object-position: " + ue(r[13]) + "; aspect-ratio=1.7778;") && a(e, "style", i), o & 32 && l !== (l = r[13].media[0].name) && a(e, "alt", l), o & 33 && !H(e.src, n = r[0] + "/media/thumb/" + r[13].media[0].url) && a(e, "src", n);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
function ae(t) { function ae(t) {
let e, i = t[12].place.address + "", l; let e, i = t[13].place.address + "", l;
return { return {
c() { c() {
e = m("span"), l = $(i), a(e, "class", "subtitle"); e = m("span"), l = z(i), a(e, "class", "subtitle");
}, },
m(n, r) { m(n, r) {
p(n, e, r), u(e, l); k(n, e, r), u(e, l);
}, },
p(n, r) { p(n, r) {
r & 32 && i !== (i = n[12].place.address + "") && T(l, i); r & 32 && i !== (i = n[13].place.address + "") && T(l, i);
}, },
d(n) { d(n) {
n && k(e); n && x(e);
} }
}; };
} }
function se(t) { function se(t) {
let e, i = t[12].tags, l = []; let e, i = t[13].tags, l = [];
for (let n = 0; n < i.length; n += 1) for (let n = 0; n < i.length; n += 1)
l[n] = ce(ie(t, i, n)); l[n] = ce(ie(t, i, n));
return { return {
@ -372,13 +372,13 @@ function se(t) {
a(e, "class", "tags"); a(e, "class", "tags");
}, },
m(n, r) { m(n, r) {
p(n, e, r); k(n, e, r);
for (let o = 0; o < l.length; o += 1) for (let o = 0; o < l.length; o += 1)
l[o].m(e, null); l[o].m(e, null);
}, },
p(n, r) { p(n, r) {
if (r & 32) { if (r & 32) {
i = n[12].tags; i = n[13].tags;
let o; let o;
for (o = 0; o < i.length; o += 1) { for (o = 0; o < i.length; o += 1) {
const f = ie(n, i, o); const f = ie(n, i, o);
@ -390,42 +390,41 @@ function se(t) {
} }
}, },
d(n) { d(n) {
n && k(e), be(l, n); n && x(e), be(l, n);
} }
}; };
} }
function ce(t) { function ce(t) {
let e, i, l = t[15] + "", n; let e, i, l = t[16] + "", n;
return { return {
c() { c() {
e = m("span"), i = $("#"), n = $(l), a(e, "class", "tag"); e = m("span"), i = z("#"), n = z(l), a(e, "class", "tag");
}, },
m(r, o) { m(r, o) {
p(r, e, o), u(e, i), u(e, n); k(r, e, o), u(e, i), u(e, n);
}, },
p(r, o) { p(r, o) {
o & 32 && l !== (l = r[15] + "") && T(n, l); o & 32 && l !== (l = r[16] + "") && T(n, l);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
function fe(t) { function fe(t) {
let e, i, l, n, r = V(t[12]) + "", o, f, c, s = t[12].title + "", w, g, _, A, y = t[12].place.name + "", d, z, h, v, C, q, E = t[3] !== "true" && oe(t), j = t[12].place.name !== "online" && ae(t), S = t[12].tags.length && se(t); let e, i, l, n, r = V(t[13]) + "", o, f, s, c = t[13].title + "", w, g, _, A, E = t[13].place.name + "", M, d, h, p, v, q, $ = t[3] !== "true" && oe(t), j = t[13].place.name !== "online" && ae(t), S = t[13].tags.length && se(t);
return { return {
c() { c() {
e = m("a"), E && E.c(), i = M(), l = m("div"), n = m("div"), o = $(r), f = M(), c = m("div"), w = $(s), g = M(), _ = m("span"), A = $('@"'), d = $(y), z = $(`" e = m("a"), $ && $.c(), i = C(), l = m("div"), n = m("div"), o = z(r), f = C(), s = m("div"), w = z(c), g = C(), _ = m("span"), A = z("@"), M = z(E), d = C(), j && j.c(), h = C(), S && S.c(), p = C(), a(n, "class", "subtitle"), a(s, "class", "title"), a(_, "class", "place"), a(l, "class", "content"), a(e, "href", v = t[0] + "/event/" + (t[13].slug || t[13].id)), a(e, "class", "event"), a(e, "title", q = t[13].title), a(e, "target", "_blank");
`), j && j.c(), h = M(), S && S.c(), v = M(), a(n, "class", "subtitle"), a(c, "class", "title"), a(_, "class", "place"), a(l, "class", "content"), a(e, "href", C = t[0] + "/event/" + (t[12].slug || t[12].id)), a(e, "class", "event"), a(e, "title", q = t[12].title), a(e, "target", "_blank");
}, },
m(b, N) { m(b, N) {
p(b, e, N), E && E.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, c), u(c, w), u(l, g), u(l, _), u(_, A), u(_, d), u(_, z), j && j.m(_, null), u(l, h), S && S.m(l, null), u(e, v); k(b, e, N), $ && $.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, s), u(s, w), u(l, g), u(l, _), u(_, A), u(_, M), u(_, d), j && j.m(_, null), u(l, h), S && S.m(l, null), u(e, p);
}, },
p(b, N) { p(b, N) {
b[3] !== "true" ? E ? E.p(b, N) : (E = oe(b), E.c(), E.m(e, i)) : E && (E.d(1), E = null), N & 32 && r !== (r = V(b[12]) + "") && T(o, r), N & 32 && s !== (s = b[12].title + "") && T(w, s), N & 32 && y !== (y = b[12].place.name + "") && T(d, y), b[12].place.name !== "online" ? j ? j.p(b, N) : (j = ae(b), j.c(), j.m(_, null)) : j && (j.d(1), j = null), b[12].tags.length ? S ? S.p(b, N) : (S = se(b), S.c(), S.m(l, null)) : S && (S.d(1), S = null), N & 33 && C !== (C = b[0] + "/event/" + (b[12].slug || b[12].id)) && a(e, "href", C), N & 32 && q !== (q = b[12].title) && a(e, "title", q); b[3] !== "true" ? $ ? $.p(b, N) : ($ = oe(b), $.c(), $.m(e, i)) : $ && ($.d(1), $ = null), N & 32 && r !== (r = V(b[13]) + "") && T(o, r), N & 32 && c !== (c = b[13].title + "") && T(w, c), N & 32 && E !== (E = b[13].place.name + "") && T(M, E), b[13].place.name !== "online" ? j ? j.p(b, N) : (j = ae(b), j.c(), j.m(_, null)) : j && (j.d(1), j = null), b[13].tags.length ? S ? S.p(b, N) : (S = se(b), S.c(), S.m(l, null)) : S && (S.d(1), S = null), N & 33 && v !== (v = b[0] + "/event/" + (b[13].slug || b[13].id)) && a(e, "href", v), N & 32 && q !== (q = b[13].title) && a(e, "title", q);
}, },
d(b) { d(b) {
b && k(e), E && E.d(), j && j.d(), S && S.d(); b && x(e), $ && $.d(), j && j.d(), S && S.d();
} }
}; };
} }
@ -433,10 +432,10 @@ function Ge(t) {
let e, i, l = t[4] && le(t), n = t[5].length && ne(t); let e, i, l = t[4] && le(t), n = t[5].length && ne(t);
return { return {
c() { c() {
l && l.c(), e = M(), n && n.c(), i = pe(), this.c = G; l && l.c(), e = C(), n && n.c(), i = pe(), this.c = G;
}, },
m(r, o) { m(r, o) {
l && l.m(r, o), p(r, e, o), n && n.m(r, o), p(r, i, o); l && l.m(r, o), k(r, e, o), n && n.m(r, o), k(r, i, o);
}, },
p(r, [o]) { p(r, [o]) {
r[4] ? l ? l.p(r, o) : (l = le(r), l.c(), l.m(e.parentNode, e)) : l && (l.d(1), l = null), r[5].length ? n ? n.p(r, o) : (n = ne(r), n.c(), n.m(i.parentNode, i)) : n && (n.d(1), n = null); r[4] ? l ? l.p(r, o) : (l = le(r), l.c(), l.m(e.parentNode, e)) : l && (l.d(1), l = null), r[5].length ? n ? n.p(r, o) : (n = ne(r), n.c(), n.m(i.parentNode, i)) : n && (n.d(1), n = null);
@ -444,7 +443,7 @@ function Ge(t) {
i: G, i: G,
o: G, o: G,
d(r) { d(r) {
l && l.d(r), r && k(e), n && n.d(r), r && k(i); l && l.d(r), r && x(e), n && n.d(r), r && x(i);
} }
}; };
} }
@ -456,34 +455,37 @@ function ue(t) {
return "center center"; return "center center";
} }
function He(t, e, i) { function He(t, e, i) {
let { baseurl: l = "" } = e, { title: n = "" } = e, { maxlength: r = !1 } = e, { tags: o = "" } = e, { places: f = "" } = e, { theme: c = "light" } = e, { show_recurrent: s = !1 } = e, { sidebar: w = "true" } = e, { external_style: g = "" } = e, _ = !1, A = []; let { baseurl: l = "" } = e, { title: n = "" } = e, { maxlength: r = !1 } = e, { collection: o = "" } = e, { tags: f = "" } = e, { places: s = "" } = e, { theme: c = "light" } = e, { show_recurrent: w = !1 } = e, { sidebar: g = "true" } = e, { external_style: _ = "" } = e, A = !1, E = [];
function y(d) { function M(d) {
if (!_) if (!A)
return; return;
const z = []; const h = [];
r && z.push(`max=${r}`), o && z.push(`tags=${o}`), f && z.push(`places=${f}`), z.push(`show_recurrent=${s ? "true" : "false"}`), fetch(`${l}/api/events?${z.join("&")}`).then((h) => h.json()).then((h) => { r && h.push(`max=${r}`);
i(5, A = h); let p = "/api/events";
}).catch((h) => { o ? p = `/api/collections/${o}` : (f && h.push(`tags=${f}`), s && h.push(`places=${s}`)), h.push(`show_recurrent=${w ? "true" : "false"}`), fetch(`${l}${p}?${h.join("&")}`).then((v) => v.json()).then((v) => {
console.error("Error loading Gancio API -> ", h); i(5, E = v.events || v);
}).catch((v) => {
console.error("Error loading Gancio API -> ", v);
}); });
} }
return ke(() => { return ke(() => {
_ = !0, y(); A = !0, M();
}), t.$$set = (d) => { }), t.$$set = (d) => {
"baseurl" in d && i(0, l = d.baseurl), "title" in d && i(1, n = d.title), "maxlength" in d && i(6, r = d.maxlength), "tags" in d && i(7, o = d.tags), "places" in d && i(8, f = d.places), "theme" in d && i(2, c = d.theme), "show_recurrent" in d && i(9, s = d.show_recurrent), "sidebar" in d && i(3, w = d.sidebar), "external_style" in d && i(4, g = d.external_style); "baseurl" in d && i(0, l = d.baseurl), "title" in d && i(1, n = d.title), "maxlength" in d && i(6, r = d.maxlength), "collection" in d && i(7, o = d.collection), "tags" in d && i(8, f = d.tags), "places" in d && i(9, s = d.places), "theme" in d && i(2, c = d.theme), "show_recurrent" in d && i(10, w = d.show_recurrent), "sidebar" in d && i(3, g = d.sidebar), "external_style" in d && i(4, _ = d.external_style);
}, t.$$.update = () => { }, t.$$.update = () => {
t.$$.dirty & 975 && y(); t.$$.dirty & 1999 && M();
}, [ }, [
l, l,
n, n,
c, c,
w,
g, g,
A, _,
E,
r, r,
o, o,
f, f,
s s,
w
]; ];
} }
class Re extends X { class Re extends X {
@ -508,21 +510,23 @@ class Re extends X {
baseurl: 0, baseurl: 0,
title: 1, title: 1,
maxlength: 6, maxlength: 6,
tags: 7, collection: 7,
places: 8, tags: 8,
places: 9,
theme: 2, theme: 2,
show_recurrent: 9, show_recurrent: 10,
sidebar: 3, sidebar: 3,
external_style: 4 external_style: 4
}, },
null null
), e && (e.target && p(e.target, this, e.anchor), e.props && (this.$set(e.props), x())); ), e && (e.target && k(e.target, this, e.anchor), e.props && (this.$set(e.props), y()));
} }
static get observedAttributes() { static get observedAttributes() {
return [ return [
"baseurl", "baseurl",
"title", "title",
"maxlength", "maxlength",
"collection",
"tags", "tags",
"places", "places",
"theme", "theme",
@ -535,72 +539,78 @@ class Re extends X {
return this.$$.ctx[0]; return this.$$.ctx[0];
} }
set baseurl(e) { set baseurl(e) {
this.$$set({ baseurl: e }), x(); this.$$set({ baseurl: e }), y();
} }
get title() { get title() {
return this.$$.ctx[1]; return this.$$.ctx[1];
} }
set title(e) { set title(e) {
this.$$set({ title: e }), x(); this.$$set({ title: e }), y();
} }
get maxlength() { get maxlength() {
return this.$$.ctx[6]; return this.$$.ctx[6];
} }
set maxlength(e) { set maxlength(e) {
this.$$set({ maxlength: e }), x(); this.$$set({ maxlength: e }), y();
} }
get tags() { get collection() {
return this.$$.ctx[7]; return this.$$.ctx[7];
} }
set tags(e) { set collection(e) {
this.$$set({ tags: e }), x(); this.$$set({ collection: e }), y();
} }
get places() { get tags() {
return this.$$.ctx[8]; return this.$$.ctx[8];
} }
set tags(e) {
this.$$set({ tags: e }), y();
}
get places() {
return this.$$.ctx[9];
}
set places(e) { set places(e) {
this.$$set({ places: e }), x(); this.$$set({ places: e }), y();
} }
get theme() { get theme() {
return this.$$.ctx[2]; return this.$$.ctx[2];
} }
set theme(e) { set theme(e) {
this.$$set({ theme: e }), x(); this.$$set({ theme: e }), y();
} }
get show_recurrent() { get show_recurrent() {
return this.$$.ctx[9]; return this.$$.ctx[10];
} }
set show_recurrent(e) { set show_recurrent(e) {
this.$$set({ show_recurrent: e }), x(); this.$$set({ show_recurrent: e }), y();
} }
get sidebar() { get sidebar() {
return this.$$.ctx[3]; return this.$$.ctx[3];
} }
set sidebar(e) { set sidebar(e) {
this.$$set({ sidebar: e }), x(); this.$$set({ sidebar: e }), y();
} }
get external_style() { get external_style() {
return this.$$.ctx[4]; return this.$$.ctx[4];
} }
set external_style(e) { set external_style(e) {
this.$$set({ external_style: e }), x(); this.$$set({ external_style: e }), y();
} }
} }
customElements.define("gancio-events", Re); customElements.define("gancio-events", Re);
function de(t) { function de(t) {
let e, i, l, n, r = t[1].title + "", o, f, c, s = V(t[1]) + "", w, g, _, A, y = t[1].place.name + "", d, z, h = t[1].media.length && he(t); let e, i, l, n, r = t[1].title + "", o, f, s, c = V(t[1]) + "", w, g, _, A, E = t[1].place.name + "", M, d, h = t[1].media.length && he(t);
return { return {
c() { c() {
e = m("a"), h && h.c(), i = M(), l = m("div"), n = m("strong"), o = $(r), f = M(), c = m("div"), w = $(s), g = M(), _ = m("div"), A = $("@"), d = $(y), a(_, "class", "place"), a(l, "class", "container"), a(e, "href", z = t[0] + "/event/" + (t[1].slug || t[1].id)), a(e, "class", "card"), a(e, "target", "_blank"); e = m("a"), h && h.c(), i = C(), l = m("div"), n = m("strong"), o = z(r), f = C(), s = m("div"), w = z(c), g = C(), _ = m("div"), A = z("@"), M = z(E), a(_, "class", "place"), a(l, "class", "container"), a(e, "href", d = t[0] + "/event/" + (t[1].slug || t[1].id)), a(e, "class", "card"), a(e, "target", "_blank");
}, },
m(v, C) { m(p, v) {
p(v, e, C), h && h.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, c), u(c, w), u(l, g), u(l, _), u(_, A), u(_, d); k(p, e, v), h && h.m(e, null), u(e, i), u(e, l), u(l, n), u(n, o), u(l, f), u(l, s), u(s, w), u(l, g), u(l, _), u(_, A), u(_, M);
}, },
p(v, C) { p(p, v) {
v[1].media.length ? h ? h.p(v, C) : (h = he(v), h.c(), h.m(e, i)) : h && (h.d(1), h = null), C & 2 && r !== (r = v[1].title + "") && T(o, r), C & 2 && s !== (s = V(v[1]) + "") && T(w, s), C & 2 && y !== (y = v[1].place.name + "") && T(d, y), C & 3 && z !== (z = v[0] + "/event/" + (v[1].slug || v[1].id)) && a(e, "href", z); p[1].media.length ? h ? h.p(p, v) : (h = he(p), h.c(), h.m(e, i)) : h && (h.d(1), h = null), v & 2 && r !== (r = p[1].title + "") && T(o, r), v & 2 && c !== (c = V(p[1]) + "") && T(w, c), v & 2 && E !== (E = p[1].place.name + "") && T(M, E), v & 3 && d !== (d = p[0] + "/event/" + (p[1].slug || p[1].id)) && a(e, "href", d);
}, },
d(v) { d(p) {
v && k(e), h && h.d(); p && x(e), h && h.d();
} }
}; };
} }
@ -611,13 +621,13 @@ function he(t) {
e = m("img"), H(e.src, i = t[2](t[1])) || a(e, "src", i), a(e, "alt", l = t[1].media[0].name), a(e, "style", n = "object-position: " + me(t[1]) + "; aspect-ratio=1.7778;"); e = m("img"), H(e.src, i = t[2](t[1])) || a(e, "src", i), a(e, "alt", l = t[1].media[0].name), a(e, "style", n = "object-position: " + me(t[1]) + "; aspect-ratio=1.7778;");
}, },
m(r, o) { m(r, o) {
p(r, e, o); k(r, e, o);
}, },
p(r, o) { p(r, o) {
o & 2 && !H(e.src, i = r[2](r[1])) && a(e, "src", i), o & 2 && l !== (l = r[1].media[0].name) && a(e, "alt", l), o & 2 && n !== (n = "object-position: " + me(r[1]) + "; aspect-ratio=1.7778;") && a(e, "style", n); o & 2 && !H(e.src, i = r[2](r[1])) && a(e, "src", i), o & 2 && l !== (l = r[1].media[0].name) && a(e, "alt", l), o & 2 && n !== (n = "object-position: " + me(r[1]) + "; aspect-ratio=1.7778;") && a(e, "style", n);
}, },
d(r) { d(r) {
r && k(e); r && x(e);
} }
}; };
} }
@ -628,7 +638,7 @@ function Ie(t) {
i && i.c(), e = pe(), this.c = G; i && i.c(), e = pe(), this.c = G;
}, },
m(l, n) { m(l, n) {
i && i.m(l, n), p(l, e, n); i && i.m(l, n), k(l, e, n);
}, },
p(l, [n]) { p(l, [n]) {
l[1] ? i ? i.p(l, n) : (i = de(l), i.c(), i.m(e.parentNode, e)) : i && (i.d(1), i = null); l[1] ? i ? i.p(l, n) : (i = de(l), i.c(), i.m(e.parentNode, e)) : i && (i.d(1), i = null);
@ -636,7 +646,7 @@ function Ie(t) {
i: G, i: G,
o: G, o: G,
d(l) { d(l) {
i && i.d(l), l && k(e); i && i.d(l), l && x(e);
} }
}; };
} }
@ -649,20 +659,20 @@ function me(t) {
} }
function Oe(t, e, i) { function Oe(t, e, i) {
let { baseurl: l = "https://demo.gancio.org" } = e, { id: n } = e, r = !1, o; let { baseurl: l = "https://demo.gancio.org" } = e, { id: n } = e, r = !1, o;
function f(s, w) { function f(c, w) {
r && fetch(`${w}/api/event/detail/${s}`).then((g) => g.json()).then((g) => i(1, o = g)); r && fetch(`${w}/api/event/detail/${c}`).then((g) => g.json()).then((g) => i(1, o = g));
} }
ke(() => { ke(() => {
r = !0, f(n, l); r = !0, f(n, l);
}); });
function c(s) { function s(c) {
return `${l}/media/thumb/${s.media[0].url}`; return `${l}/media/thumb/${c.media[0].url}`;
} }
return t.$$set = (s) => { return t.$$set = (c) => {
"baseurl" in s && i(0, l = s.baseurl), "id" in s && i(3, n = s.id); "baseurl" in c && i(0, l = c.baseurl), "id" in c && i(3, n = c.id);
}, t.$$.update = () => { }, t.$$.update = () => {
t.$$.dirty & 9 && f(n, l); t.$$.dirty & 9 && f(n, l);
}, [l, o, c, n]; }, [l, o, s, n];
} }
class Ue extends X { class Ue extends X {
constructor(e) { constructor(e) {
@ -679,7 +689,7 @@ class Ue extends X {
_e, _e,
{ baseurl: 0, id: 3 }, { baseurl: 0, id: 3 },
null null
), e && (e.target && p(e.target, this, e.anchor), e.props && (this.$set(e.props), x())); ), e && (e.target && k(e.target, this, e.anchor), e.props && (this.$set(e.props), y()));
} }
static get observedAttributes() { static get observedAttributes() {
return ["baseurl", "id"]; return ["baseurl", "id"];
@ -688,13 +698,13 @@ class Ue extends X {
return this.$$.ctx[0]; return this.$$.ctx[0];
} }
set baseurl(e) { set baseurl(e) {
this.$$set({ baseurl: e }), x(); this.$$set({ baseurl: e }), y();
} }
get id() { get id() {
return this.$$.ctx[3]; return this.$$.ctx[3];
} }
set id(e) { set id(e) {
this.$$set({ id: e }), x(); this.$$set({ id: e }), y();
} }
} }
customElements.define("gancio-event", Ue); customElements.define("gancio-event", Ue);

4334
yarn.lock

File diff suppressed because it is too large Load diff