Compare commits

..

67 commits

Author SHA1 Message Date
johndoe4 f12e39c907 Merge branch 'main' of https://framagit.org/framasoft/mobilizon into fomo-3.1.0 2023-06-13 01:05:41 +02:00
Thomas Citharel 80f73a34a6 Merge branch 'fix-pruning-old-app-activations' into 'main'
fix(apps): fix pruning old application device activations

See merge request framasoft/mobilizon!1411
2023-06-06 12:10:28 +00:00
Thomas Citharel cde171d497 Merge branch 'fix-losing-relay-private-keys' into 'main'
Federation fixes

See merge request framasoft/mobilizon!1410
2023-06-06 10:54:00 +00:00
Thomas Citharel dd00620b9a
fix(apps): fix pruning old application device activations
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-06-06 12:47:38 +02:00
Thomas Citharel 5381eaae22
fix(federation): rotate relay keys on startup if missing private keys
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-06-06 12:20:35 +02:00
Thomas Citharel 6745590e54
fix(federation): only refresh instances once a day
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-06-06 12:12:19 +02:00
Thomas Citharel d300f9deea Merge branch 'fix-losing-relay-private-keys' into 'main'
fix(federation): prevent fetching own relay actor

See merge request framasoft/mobilizon!1409
2023-06-06 09:57:10 +00:00
Thomas Citharel e8d34b4ea9
fix(federation): restrict fetch_group first arg to binaries
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-06-06 09:57:14 +02:00
Thomas Citharel b981f91cf7
fix(federation): prevent fetching own relay actor
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-06-06 09:52:46 +02:00
Thomas Citharel 99db295310 Merge branch 'weblate-mobilizon-frontend' into 'main'
Translations update from Framasoft Weblate

See merge request framasoft/mobilizon!1408
2023-06-05 21:19:47 +00:00
Milo Ivir b6f5eed67c Translated using Weblate (Croatian)
Currently translated at 85.4% (1338 of 1566 strings)

Translation: Mobilizon/Frontend
Translate-URL: https://weblate.framasoft.org/projects/mobilizon/frontend/hr/
2023-06-05 21:43:49 +02:00
johndoe4 113ea75ed6 Fix Eventview Rows in 3.1.0 2023-06-01 19:59:09 +02:00
johndoe4 d945361341 Merge branch 'main' of https://framagit.org/framasoft/mobilizon into fomo-3.1.0
Update to 3.1.0
2023-06-01 19:42:15 +02:00
johndoe4 8e24754d08 yellow-1 2023-06-01 00:46:05 +02:00
johndoe4 00fb3b54a8 Some more color changes 2023-06-01 00:41:56 +02:00
johndoe4 167cc1d83e Shape SVGs in FOMO colors 2023-05-30 23:48:00 +02:00
johndoe4 916bf617fd Max-width fix(mobile 2.1.0-rc.2) 2023-05-30 23:20:29 +02:00
johndoe4 f898936e2a Merge branch 'main' of https://framagit.org/framasoft/mobilizon into fomo-3.1.0 2023-05-30 17:53:49 +02:00
johndoe4 8260d62681 Some Color changes 2023-05-27 22:14:45 +02:00
johndoe4 9154c24332 Footer: Remove Picture & change bg-color 2023-05-27 09:39:07 +02:00
johndoe4 e9680509bf Uncomment unnecessary stuff from HomeView 2023-05-27 09:31:56 +02:00
johndoe4 3f03e320d1 show events until their end time, unless they have no end time 2023-05-27 09:23:42 +02:00
johndoe4 609740f931 Merge branch 'main' of https://framagit.org/framasoft/mobilizon into fomo-3.1.0 2023-05-26 13:12:20 +02:00
johndoe4 3197e3d588 Add Venue-Name to InlineAddress(for Eventcard) 2023-05-26 10:59:03 +02:00
johndoe4 2eb5c4fa87 NavBar Fix(Textcolor) 2023-05-26 10:30:15 +02:00
johndoe4 62d4b5a789 Always Dark NavBar 2023-05-26 10:21:44 +02:00
johndoe4 0e9fae5173 Add Fomo Logo 2023-05-26 08:58:16 +02:00
johndoe4 f768f1672b Replace and add Fomo specific pictures 2023-05-26 08:57:37 +02:00
778a69cd 0d804cba1f include nodejs in devShell 2023-05-24 17:16:01 +02:00
778a69cd 4284e8e635 Merge remote-tracking branch 'origin/main' 2023-05-24 13:00:37 +02:00
Thomas Citharel 7defbe6bc9 chore(changelog): fix changelog version and move an element in the correct section
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-05-23 14:37:13 +02:00
Thomas Citharel 26e22edfc0 build(docker-tests): Update test container
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-05-23 14:37:13 +02:00
Thomas Citharel ba3a52cd4b build(docker): Fix production Dockerfile
Make sure every data folder properly exists

See https://forge.tedomum.net/tedomum/mobilizon/-/issues/14

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-05-23 14:37:13 +02:00
johndoe4 08764fff72 Adding Starttime to Eventcards and Header 2023-05-23 01:30:53 +02:00
johndoe4 a50b9128fe Adding Weekday to .datetime-container-header 2023-05-22 23:12:55 +02:00
johndoe4 be8a206b0d Things commented out which in my opinion are no longer needed 6bcff6d1ae 2023-05-22 00:52:05 +02:00
johndoe4 04e7a2e02d revert 96871853d1
revert Removed some unnecessary stuff
2023-05-22 00:28:49 +02:00
johndoe4 96871853d1 Removed some unnecessary stuff 2023-05-22 00:22:45 +02:00
johndoe4 6bcff6d1ae Use Columns and Rows instead of scrolling 2023-05-22 00:21:09 +02:00
778a69cd 7127b0da28 Merge remote-tracking branch 'origin/main' 2023-05-17 17:51:20 +02:00
778a69cd cba53e2e9d remove phoenix.json_library config 2023-05-17 17:35:11 +02:00
778a69cd 1fac112942 mix deps.update ex_cldr ex_cldr_numbers 2023-05-17 17:19:32 +02:00
johndoe4 c5ecaf5d7c Fix for Commit 2072402e98
- forgot to change the variable name
2023-05-17 16:55:14 +02:00
johndoe4 974c73e071 Temp. Fix: mbz-cards didnt get a fixed (max) width on small screens
- Add a max-width and width for mbz-card in App.vue
2023-05-17 00:59:36 +02:00
johndoe4 2072402e98 Adding UpcomingEvents.vue & include it to HomeView.vue
- Will show all upcoming Events sorted by Date on the Startpage
2023-05-17 00:52:22 +02:00
summersamara 67765a645e read logo from separate svg file for easier customization 2023-05-16 21:19:49 +02:00
summersamara f887455d66 make vite server reachable from outside the container
[fix #1225] https://framagit.org/framasoft/mobilizon/-/issues/1225
2023-05-16 21:19:49 +02:00
778a69cd d52dc72f9a flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/0470f36b02ef01d4f43c641bbf07020bcab71bf1' (2023-05-14)
  → 'github:NixOS/nixpkgs/963006aab35e3e8ebbf6052b6bf4ea712fdd3c28' (2023-05-16)
2023-05-16 20:47:34 +02:00
778a69cd 0b73264392 add yarn2nix to flake.nix 2023-05-16 20:45:49 +02:00
778a69cd cc89e9f98e Merge branch 'potsda.mn-3.0.4' 2023-05-16 20:41:30 +02:00
778a69cd 609512a9ed use latest nixos-unstable in devShell, add mix2nix 2023-05-16 17:32:48 +02:00
summersamara 773ddd22a7 add elixir version 1.13.4 to Dockerfile for dev 2023-05-16 17:32:48 +02:00
778a69cd 8e00c78a11 use yarn with an older nodejs version in devShell 2023-05-16 17:32:48 +02:00
778a69cd d830597206 use nixpkgs from september 2022 for nix devShell 2023-05-16 17:32:47 +02:00
778a69cd 438f1dde3e init nix flake 2023-05-16 17:32:47 +02:00
778a69cd d2af20dd59 show events until their end time, unless they have no end time 2023-05-16 17:32:47 +02:00
778a69cd aa043d8793 fix wrong link in instance follow request email
this is upstreamable
2023-05-16 17:32:47 +02:00
778a69cd 23378a378a add Mobilizon version to instance config 2023-05-16 17:32:47 +02:00
778a69cd 0824694c56 Revert "default anonymous participation in events to true"
This reverts commit 3a1b7a4660b4fd9488e7d06e677027ae41e0c10c.
2023-05-16 17:32:47 +02:00
778a69cd dcd097bf6d default anonymous participation in events to true 2023-05-16 17:32:47 +02:00
778a69cd d53f7b93e9 Use our own categories for event creation 2023-05-16 17:32:47 +02:00
778a69cd 1b9aafa855 remove pictures for error and 404 site 2023-05-15 19:36:58 +02:00
Thomas Citharel 0837090e30
Bump version to 3.0.4
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-03-20 18:26:59 +01:00
Thomas Citharel 5bb09927a3 Merge branch 'v3.0.4' into 'stable-3.0'
Fix LDAP and participant export

See merge request framasoft/mobilizon!1362
2023-03-20 16:14:38 +00:00
Thomas Citharel 20fc9d1f6b
Fetch config for export event participant formats
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-03-20 16:39:27 +01:00
Thomas Citharel cef536d5b9
Fix LDAP authentificator tests
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-03-20 13:07:02 +01:00
ljf 48ebdbb03a
[fix] LDAP connector with erland 24.3+ 2023-03-20 12:26:06 +01:00
74 changed files with 637 additions and 336 deletions

View file

@ -1,4 +1,4 @@
FROM elixir:alpine FROM elixir:1.13.4-alpine
RUN apk add --no-cache inotify-tools postgresql-client yarn file make gcc libc-dev argon2 imagemagick cmake build-base libwebp-tools bash ncurses git python3 RUN apk add --no-cache inotify-tools postgresql-client yarn file make gcc libc-dev argon2 imagemagick cmake build-base libwebp-tools bash ncurses git python3
@ -7,3 +7,4 @@ RUN mix local.hex --force && mix local.rebar --force
WORKDIR /app WORKDIR /app
EXPOSE 4000 EXPOSE 4000
EXPOSE 5173

View file

@ -189,7 +189,6 @@ config :mobilizon, Mobilizon.Service.Formatter,
config :tesla, adapter: Tesla.Adapter.Hackney config :tesla, adapter: Tesla.Adapter.Hackney
config :phoenix, :format_encoders, json: Jason, "activity-json": Jason config :phoenix, :format_encoders, json: Jason, "activity-json": Jason
config :phoenix, :json_library, Jason
config :phoenix, :filter_parameters, ["password", "token"] config :phoenix, :filter_parameters, ["password", "token"]
config :absinthe, schema: Mobilizon.GraphQL.Schema config :absinthe, schema: Mobilizon.GraphQL.Schema
@ -307,7 +306,7 @@ config :mobilizon, Oban,
crontab: [ crontab: [
{"@hourly", Mobilizon.Service.Workers.BuildSiteMap, queue: :background}, {"@hourly", Mobilizon.Service.Workers.BuildSiteMap, queue: :background},
{"17 4 * * *", Mobilizon.Service.Workers.RefreshGroups, queue: :background}, {"17 4 * * *", Mobilizon.Service.Workers.RefreshGroups, queue: :background},
{"36 * * * *", Mobilizon.Service.Workers.RefreshInstances, queue: :background}, {"36 3 * * *", Mobilizon.Service.Workers.RefreshInstances, queue: :background},
{"@hourly", Mobilizon.Service.Workers.CleanOrphanMediaWorker, queue: :background}, {"@hourly", Mobilizon.Service.Workers.CleanOrphanMediaWorker, queue: :background},
{"@hourly", Mobilizon.Service.Workers.CleanUnconfirmedUsersWorker, queue: :background}, {"@hourly", Mobilizon.Service.Workers.CleanUnconfirmedUsersWorker, queue: :background},
{"@hourly", Mobilizon.Service.Workers.ExportCleanerWorker, queue: :background}, {"@hourly", Mobilizon.Service.Workers.ExportCleanerWorker, queue: :background},

View file

@ -19,6 +19,7 @@ services:
- ".:/app" - ".:/app"
ports: ports:
- 4000:4000 - 4000:4000
- 5173:5173
depends_on: depends_on:
- postgres - postgres
environment: environment:

27
flake.lock Normal file
View file

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1684215771,
"narHash": "sha256-fsum28z+g18yreNa1Y7MPo9dtps5h1VkHfZbYQ+YPbk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "963006aab35e3e8ebbf6052b6bf4ea712fdd3c28",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

29
flake.nix Normal file
View file

@ -0,0 +1,29 @@
{
description = "A very basic flake";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }: {
packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello;
packages.x86_64-linux.default = self.packages.x86_64-linux.hello;
devShells.x86_64-linux.default = let
pkgs = import nixpkgs { system = "x86_64-linux"; };
in pkgs.mkShell {
buildInputs = with pkgs; [
elixir
mix2nix
cmake
imagemagick
(yarn.override {
nodejs = nodejs-16_x;
})
yarn2nix
nodejs-16_x
];
};
};
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,015 B

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"><path style="opacity:1;fill:#fea72b;fill-opacity:1;stroke:none;stroke-opacity:1" d="M-5.801-6.164h72.69v72.871h-72.69z"/><g data-name="Calque 2"><g data-name="header"><path d="M26.58 27.06q0 8-4.26 12.3a12.21 12.21 0 0 1-9 3.42 12.21 12.21 0 0 1-9-3.42Q0 35.1 0 27.06q0-8.04 4.26-12.3a12.21 12.21 0 0 1 9-3.42 12.21 12.21 0 0 1 9 3.42q4.32 4.24 4.32 12.3zM13.29 17q-5.67 0-5.67 10.06t5.67 10.08q5.71 0 5.71-10.08T13.29 17z" style="fill:#3a384c;fill-opacity:1" transform="translate(14.627 5.256) scale(1.15671)"/><path d="M9 6.78a7.37 7.37 0 0 1-.6-3 7.37 7.37 0 0 1 .6-3A8.09 8.09 0 0 1 12.83 0a7.05 7.05 0 0 1 3.69.84 7.37 7.37 0 0 1 .6 3 7.37 7.37 0 0 1-.6 3 7.46 7.46 0 0 1-3.87.84A6.49 6.49 0 0 1 9 6.78z" style="fill:#fff" transform="translate(14.627 5.256) scale(1.15671)"/></g></g></svg> <svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"><path style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#3c3c3c;stroke-opacity:0" d="m -5.801,-6.164 h 72.69 v 72.871 h -72.69 z"/><g data-name="icon"><g data-name="header"><path d="M 22.046275,57.767824 H 21.898116 L 15.171689,53.856422 Q 14.964267,53.737894 14.964267,53.50084 L 14.845739,16.223989 q 0.02963,-0.207422 0.207423,-0.32595 22.964673,-13.2750625 23.083201,-13.2750625 0.118527,0 6.874586,3.9410343 l 0.05926,0.059264 0.05926,0.029632 v 0.029632 h 0.02963 l 0.05926,0.1185274 0.02963,4.5040395 q -0.02963,0.237054 -0.207423,0.355582 L 26.165101,22.535571 v 3.407661 q 11.911998,-6.874586 12.030525,-6.874586 0.0889,0 3.496557,1.985333 3.407661,1.955701 3.407661,1.985333 h 0.02963 v 0.02963 q 0.02963,0.02963 0.02963,0.05926 0.02963,0 0.02963,0 0.02963,0 0.02963,0.02963 l 0.02963,0.148159 h 0.02963 v 4.444776 q 0,0.207423 -0.207423,0.32595 l -18.845848,10.904516 0.02963,16.208614 q 0,0.207423 -0.207423,0.32595 -3.852138,2.25202 -4.000298,2.25202 z M 26.194733,33.677141 44.06273,23.365262 38.195626,19.927969 26.194733,26.861819 Z m -4.563303,22.994305 -0.0889,-36.298999 -5.867103,-3.437294 0.0889,36.328632 z M 21.927748,19.661282 44.003466,6.9195928 38.136363,3.5119316 16.060645,16.253621 Z" style="stroke-opacity:1;fill:#ffffff;stroke:#ffffff;stroke-width:0.782;stroke-dasharray:none"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 857 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"><path style="opacity:1;fill:#fea72b;fill-opacity:1;stroke:none;stroke-opacity:1" d="M-5.801-6.164h72.69v72.871h-72.69z"/><g data-name="Calque 2"><g data-name="header"><path d="M26.58 27.06q0 8-4.26 12.3a12.21 12.21 0 0 1-9 3.42 12.21 12.21 0 0 1-9-3.42Q0 35.1 0 27.06q0-8.04 4.26-12.3a12.21 12.21 0 0 1 9-3.42 12.21 12.21 0 0 1 9 3.42q4.32 4.24 4.32 12.3zM13.29 17q-5.67 0-5.67 10.06t5.67 10.08q5.71 0 5.71-10.08T13.29 17z" style="fill:#3a384c;fill-opacity:1" transform="translate(14.627 5.256) scale(1.15671)"/><path d="M9 6.78a7.37 7.37 0 0 1-.6-3 7.37 7.37 0 0 1 .6-3A8.09 8.09 0 0 1 12.83 0a7.05 7.05 0 0 1 3.69.84 7.37 7.37 0 0 1 .6 3 7.37 7.37 0 0 1-.6 3 7.46 7.46 0 0 1-3.87.84A6.49 6.49 0 0 1 9 6.78z" style="fill:#fff" transform="translate(14.627 5.256) scale(1.15671)"/></g></g></svg> <svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"><path style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#3c3c3c;stroke-opacity:0" d="m -5.801,-6.164 h 72.69 v 72.871 h -72.69 z"/><g data-name="icon"><g data-name="header"><path d="M 22.046275,57.767824 H 21.898116 L 15.171689,53.856422 Q 14.964267,53.737894 14.964267,53.50084 L 14.845739,16.223989 q 0.02963,-0.207422 0.207423,-0.32595 22.964673,-13.2750625 23.083201,-13.2750625 0.118527,0 6.874586,3.9410343 l 0.05926,0.059264 0.05926,0.029632 v 0.029632 h 0.02963 l 0.05926,0.1185274 0.02963,4.5040395 q -0.02963,0.237054 -0.207423,0.355582 L 26.165101,22.535571 v 3.407661 q 11.911998,-6.874586 12.030525,-6.874586 0.0889,0 3.496557,1.985333 3.407661,1.955701 3.407661,1.985333 h 0.02963 v 0.02963 q 0.02963,0.02963 0.02963,0.05926 0.02963,0 0.02963,0 0.02963,0 0.02963,0.02963 l 0.02963,0.148159 h 0.02963 v 4.444776 q 0,0.207423 -0.207423,0.32595 l -18.845848,10.904516 0.02963,16.208614 q 0,0.207423 -0.207423,0.32595 -3.852138,2.25202 -4.000298,2.25202 z M 26.194733,33.677141 44.06273,23.365262 38.195626,19.927969 26.194733,26.861819 Z m -4.563303,22.994305 -0.0889,-36.298999 -5.867103,-3.437294 0.0889,36.328632 z M 21.927748,19.661282 44.003466,6.9195928 38.136363,3.5119316 16.060645,16.253621 Z" style="stroke-opacity:1;fill:#ffffff;stroke:#ffffff;stroke-width:0.782;stroke-dasharray:none"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 857 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -2,8 +2,8 @@
<svg id="sw-js-blob-svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1"> <svg id="sw-js-blob-svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs> <defs>
<linearGradient id="sw-gradient" x1="0" x2="1" y1="1" y2="0"> <linearGradient id="sw-gradient" x1="0" x2="1" y1="1" y2="0">
<stop id="stop1" stop-color="rgba(255, 231.287, 78.545, 0.3)" offset="0%"></stop> <stop id="stop1" stop-color="rgba(33, 190, 243, 0.3)" offset="0%"></stop>
<stop id="stop2" stop-color="rgba(254.848, 165.324, 149.009, 0.25)" offset="100%"></stop> <stop id="stop2" stop-color="rgba(50, 117, 191, 0.25)" offset="100%"></stop>
</linearGradient> </linearGradient>
</defs> </defs>
<path fill="url(#sw-gradient)" d="M18.2,-13.5C23.5,-7.8,27.8,-0.2,27.7,8.7C27.5,17.6,22.9,27.8,14.1,33.9C5.3,39.9,-7.8,41.6,-17.7,36.8C-27.6,32,-34.2,20.7,-37.1,8.4C-39.9,-3.9,-39,-17.2,-32.2,-23.2C-25.4,-29.3,-12.7,-28.3,-3.1,-25.8C6.4,-23.3,12.8,-19.3,18.2,-13.5Z" width="100%" height="100%" transform="translate(50 50)" style="transition: all 0.3s ease 0s;" stroke-width="0" stroke="url(#sw-gradient)"></path> <path fill="url(#sw-gradient)" d="M18.2,-13.5C23.5,-7.8,27.8,-0.2,27.7,8.7C27.5,17.6,22.9,27.8,14.1,33.9C5.3,39.9,-7.8,41.6,-17.7,36.8C-27.6,32,-34.2,20.7,-37.1,8.4C-39.9,-3.9,-39,-17.2,-32.2,-23.2C-25.4,-29.3,-12.7,-28.3,-3.1,-25.8C6.4,-23.3,12.8,-19.3,18.2,-13.5Z" width="100%" height="100%" transform="translate(50 50)" style="transition: all 0.3s ease 0s;" stroke-width="0" stroke="url(#sw-gradient)"></path>

Before

Width:  |  Height:  |  Size: 1,015 B

After

Width:  |  Height:  |  Size: 994 B

View file

@ -2,8 +2,8 @@
<svg id="sw-js-blob-svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1"> <svg id="sw-js-blob-svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs> <defs>
<linearGradient id="sw-gradient" x1="0" x2="1" y1="1" y2="0"> <linearGradient id="sw-gradient" x1="0" x2="1" y1="1" y2="0">
<stop id="stop1" stop-color="rgba(181.058, 255, 167.816, 0.2)" offset="0%"></stop> <stop id="stop1" stop-color="rgba(33, 190, 243, 0.2)" offset="0%"></stop>
<stop id="stop2" stop-color="rgba(149.009, 254.848, 251.263, 0.25)" offset="100%"></stop> <stop id="stop2" stop-color="rgba(228, 76, 226, 0.25)" offset="100%"></stop>
</linearGradient> </linearGradient>
</defs> </defs>
<path fill="url(#sw-gradient)" d="M20.2,-14.3C28.2,-6,38.3,2.5,37.6,9.8C36.9,17.1,25.5,23.1,15.5,25.2C5.6,27.3,-2.9,25.4,-11.2,21.9C-19.6,18.4,-27.9,13.3,-30.8,5.6C-33.7,-2.1,-31.2,-12.5,-25.2,-20.4C-19.1,-28.3,-9.6,-33.7,-1.8,-32.3C6.1,-30.9,12.1,-22.7,20.2,-14.3Z" width="100%" height="100%" transform="translate(50 50)" style="transition: all 0.3s ease 0s;" stroke-width="0" stroke="url(#sw-gradient)"></path> <path fill="url(#sw-gradient)" d="M20.2,-14.3C28.2,-6,38.3,2.5,37.6,9.8C36.9,17.1,25.5,23.1,15.5,25.2C5.6,27.3,-2.9,25.4,-11.2,21.9C-19.6,18.4,-27.9,13.3,-30.8,5.6C-33.7,-2.1,-31.2,-12.5,-25.2,-20.4C-19.1,-28.3,-9.6,-33.7,-1.8,-32.3C6.1,-30.9,12.1,-22.7,20.2,-14.3Z" width="100%" height="100%" transform="translate(50 50)" style="transition: all 0.3s ease 0s;" stroke-width="0" stroke="url(#sw-gradient)"></path>

Before

Width:  |  Height:  |  Size: 1,016 B

After

Width:  |  Height:  |  Size: 994 B

View file

@ -2,8 +2,8 @@
<svg id="sw-js-blob-svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1"> <svg id="sw-js-blob-svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs> <defs>
<linearGradient id="sw-gradient" x1="0" x2="1" y1="1" y2="0"> <linearGradient id="sw-gradient" x1="0" x2="1" y1="1" y2="0">
<stop id="stop1" stop-color="rgba(172.198, 167.816, 255, 0.2)" offset="0%"></stop> <stop id="stop1" stop-color="rgba(206, 61, 204, 0.2)" offset="0%"></stop>
<stop id="stop2" stop-color="rgba(236.8, 149.009, 254.848, 0.25)" offset="100%"></stop> <stop id="stop2" stop-color="rgba(158, 158, 242, 0.25)" offset="100%"></stop>
</linearGradient> </linearGradient>
</defs> </defs>
<path fill="url(#sw-gradient)" d="M25.3,-21.5C29.4,-15.2,26.8,-4.8,23.6,3.8C20.4,12.5,16.5,19.4,10.2,23.2C3.9,27,-4.8,27.6,-12.6,24.5C-20.3,21.4,-27,14.6,-30.1,5.6C-33.2,-3.4,-32.6,-14.4,-26.9,-21.1C-21.3,-27.8,-10.7,-30.1,0,-30.1C10.7,-30.1,21.3,-27.8,25.3,-21.5Z" width="100%" height="100%" transform="translate(50 50)" style="transition: all 0.3s ease 0s;" stroke-width="0" stroke="url(#sw-gradient)"></path> <path fill="url(#sw-gradient)" d="M25.3,-21.5C29.4,-15.2,26.8,-4.8,23.6,3.8C20.4,12.5,16.5,19.4,10.2,23.2C3.9,27,-4.8,27.6,-12.6,24.5C-20.3,21.4,-27,14.6,-30.1,5.6C-33.2,-3.4,-32.6,-14.4,-26.9,-21.1C-21.3,-27.8,-10.7,-30.1,0,-30.1C10.7,-30.1,21.3,-27.8,25.3,-21.5Z" width="100%" height="100%" transform="translate(50 50)" style="transition: all 0.3s ease 0s;" stroke-width="0" stroke="url(#sw-gradient)"></path>

Before

Width:  |  Height:  |  Size: 1,013 B

After

Width:  |  Height:  |  Size: 994 B

View file

@ -322,6 +322,11 @@ onBeforeUnmount(() => {
} }
} }
.w-full .mbz-card {
width: 20rem;
max-width: 95%;
}
.vue-skip-to { .vue-skip-to {
z-index: 40; z-index: 40;
} }

View file

@ -0,0 +1,31 @@
<svg
class="bg-white dark:bg-zinc-900 dark:fill-white"
:class="{ 'bg-gray-900': invert }"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 248.16 46.78"
>
<title>Mobilizon Logo</title>
<g data-name="header">
<path
d="M0 45.82l3.18-40.8a29.88 29.88 0 015.07-.36 27.74 27.74 0 014.95.36l4.86 17.16a92.19 92.19 0 012.34 10.08h.36a92.19 92.19 0 012.34-10.08L28 5.02a29.23 29.23 0 015-.36 29.23 29.23 0 015 .36l3.18 40.8a13.61 13.61 0 01-3.63.42 23.41 23.41 0 01-3.63-.24l-1.2-19.92q-.36-5.52-.48-12.84h-.44l-7.32 26.51a25.62 25.62 0 01-4 .3 23.36 23.36 0 01-3.84-.3L9.36 13.24H9q-.3 8.94-.48 12.84L7.26 46a22.47 22.47 0 01-3.6.24A13.75 13.75 0 010 45.82zM74 31.06q0 8-4.26 12.3a12.21 12.21 0 01-9 3.42 12.21 12.21 0 01-9-3.42q-4.26-4.26-4.26-12.3t4.24-12.31a12.21 12.21 0 019-3.42 12.21 12.21 0 019 3.42Q74 23.02 74 31.06zM60.75 20.98q-5.67 0-5.67 10.08t5.67 10.08q5.67 0 5.67-10.08t-5.67-10.08zM103.2 19.75q2.7 4.11 2.7 11.28T102 42.31a13.18 13.18 0 01-10 4.11 31.41 31.41 0 01-11.34-2V2.2l.4-.45h2.76A4 4 0 0187 2.83a5.38 5.38 0 01.93 3.57v11.94a12.08 12.08 0 017.56-2.7 8.71 8.71 0 017.71 4.11zm-9.72 2a7.28 7.28 0 00-5.58 2.82v16a15 15 0 004.08.54 5.25 5.25 0 004.68-2.67q1.68-2.67 1.68-7.59 0-9.03-4.86-9.1zM121 22v23.94a20.85 20.85 0 01-3.66.3 23 23 0 01-3.78-.3V24.75q0-3.24-2.7-3.24h-.72a9.32 9.32 0 01-.3-2.58 10.7 10.7 0 01.3-2.7 39.63 39.63 0 014.38-.24h1a5.19 5.19 0 014 1.62A6.27 6.27 0 01121 22z"
/>
<path
d="M119.82.84a7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.93 7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.93z"
fill="currentColor"
/>
<path
d="M139.08 40.42h2a10.23 10.23 0 01.6 3.18 9.24 9.24 0 01-.18 2.1 38.47 38.47 0 01-5.64.54q-6.48 0-6.48-7v-37l.36-.42h2.88a3.94 3.94 0 013.12 1.05 5.52 5.52 0 01.9 3.57v31.31q-.02 2.67 2.44 2.67zM155.94 22v23.94a20.85 20.85 0 01-3.66.3 23 23 0 01-3.78-.3V24.75q0-3.24-2.7-3.24h-.72a9.32 9.32 0 01-.3-2.58 10.7 10.7 0 01.3-2.7 39.63 39.63 0 014.38-.24h1a5.19 5.19 0 014.05 1.62 6.27 6.27 0 011.43 4.39z"
/>
<path
d="M154.8 2.84a7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.93 7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.93z"
fill="currentColor"
/>
<path
d="M163.08 39.22l8.76-11.82q1.32-1.8 4.8-5.7l-.18-.3a63.09 63.09 0 01-7.74.42H163a9.79 9.79 0 01-.24-2.34 15.8 15.8 0 01.42-3.3h20.4a16.31 16.31 0 011 4.26 4.1 4.1 0 01-.78 2.34L175 34.66a64.65 64.65 0 01-4.56 5.7l.18.24q3.12-.3 5.22-.3h2.58a15.35 15.35 0 006.12-.9 9.4 9.4 0 01.72 3.12q0 3.42-4.32 3.42h-18a14.27 14.27 0 01-.9-3.93 5.08 5.08 0 011.04-2.79zM215.88 31.06q0 8-4.26 12.3a13.63 13.63 0 01-18.06 0q-4.26-4.26-4.26-12.3t4.26-12.31a13.63 13.63 0 0118.06 0q4.26 4.27 4.26 12.31zm-13.29-10.08q-5.67 0-5.67 10.08t5.67 10.08q5.67 0 5.67-10.08t-5.67-10.08zM247 25.84v13.32a11 11 0 001.2 5.64 7 7 0 01-4.41 1.56q-2.43 0-3.33-1.14a5.69 5.69 0 01-.9-3.54V27.4a7.74 7.74 0 00-.72-3.87 2.78 2.78 0 00-2.58-1.17 8.62 8.62 0 00-6.3 3v20.58a20.85 20.85 0 01-3.66.3 23 23 0 01-3.78-.3v-29.7l.42-.36h2.76q3.42 0 4.08 3.6 4.38-3.84 8.73-3.84t6.42 2.82a12.17 12.17 0 012.07 7.38z"
/>
<path
d="M57.26 10.75a7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.84 7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.84zM198.26 10.75a7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.84 7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.84z"
fill="currentColor"
/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View file

@ -24,7 +24,7 @@
@layer components { @layer components {
.mbz-card { .mbz-card {
@apply block bg-mbz-yellow-alt-300 hover:bg-mbz-yellow-alt-200 text-violet-title dark:text-white dark:hover:text-white rounded-lg dark:border-violet-title shadow-md dark:bg-mbz-purple dark:hover:dark:bg-mbz-purple-400 dark:text-white dark:hover:text-white; @apply block bg-white hover:bg-gray-100 text-violet-title dark:text-white dark:hover:text-white rounded-lg dark:border-violet-title shadow-md dark:bg-mbz-purple dark:hover:dark:bg-mbz-purple-400 dark:text-white dark:hover:text-white;
} }
} }

View file

@ -10,7 +10,7 @@
> >
<MapMarker /> <MapMarker />
<span v-if="physicalAddress.locality"> <span v-if="physicalAddress.locality">
{{ physicalAddress.locality }} {{ physicalAddress.description }}, {{ physicalAddress.locality }}
</span> </span>
<span v-else> <span v-else>
{{ physicalAddress.description }} {{ physicalAddress.description }}

View file

@ -4,7 +4,11 @@
:class="{ small }" :class="{ small }"
:style="`--small: ${smallStyle}`" :style="`--small: ${smallStyle}`"
> >
<div class="datetime-container-header" /> <div class="datetime-container-header">
<time :datetime="dateObj.toISOString()" class="weekday">{{
weekday
}}</time>
</div>
<div class="datetime-container-content"> <div class="datetime-container-content">
<time :datetime="dateObj.toISOString()" class="day block font-semibold">{{ <time :datetime="dateObj.toISOString()" class="day block font-semibold">{{
day day
@ -12,12 +16,12 @@
<time <time
:datetime="dateObj.toISOString()" :datetime="dateObj.toISOString()"
class="month font-semibold block uppercase py-1 px-0" class="month font-semibold block uppercase py-1 px-0"
>{{ month }}</time >{{ month }}</time>
>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { localeShortWeekDayNames } from "@/utils/datetime";
import { computed } from "vue"; import { computed } from "vue";
const props = withDefaults( const props = withDefaults(
@ -38,6 +42,10 @@ const day = computed<string>(() =>
dateObj.value.toLocaleString(undefined, { day: "numeric" }) dateObj.value.toLocaleString(undefined, { day: "numeric" })
); );
const weekday = computed<string>(() =>
dateObj.value.toLocaleString(undefined, { weekday: "short" })
);
const smallStyle = computed<string>(() => (props.small ? "1.2" : "2")); const smallStyle = computed<string>(() => (props.small ? "1.2" : "2"));
</script> </script>
@ -51,6 +59,13 @@ div.datetime-container {
height: calc(10px * var(--small)); height: calc(10px * var(--small));
background: #f3425f; background: #f3425f;
} }
.datetime-container-header .weekday
{
font-size: calc(9px * var(--small));
font-weight: bold;
vertical-align: top;
line-height: calc(9px * var(--small));
}
.datetime-container-content { .datetime-container-content {
height: calc(30px * var(--small)); height: calc(30px * var(--small));
} }

View file

@ -3,7 +3,7 @@
class="mbz-card snap-center dark:bg-mbz-purple" class="mbz-card snap-center dark:bg-mbz-purple"
:class="{ :class="{
'sm:flex sm:items-start': mode === 'row', 'sm:flex sm:items-start': mode === 'row',
'sm:max-w-xs w-[18rem] shrink-0 flex flex-col': mode === 'column', 'sm:max-w-xs shrink-0 flex flex-col': mode === 'column',
}" }"
:to="to" :to="to"
:isInternal="isInternal" :isInternal="isInternal"
@ -58,6 +58,16 @@
:date="event.beginsOn.toString()" :date="event.beginsOn.toString()"
/> />
</div> </div>
<div
class="-mt-3 h-0 flex mb-3 ltr:ml-0 rtl:mr-0 items-end self-end"
:class="{ 'sm:hidden': mode === 'row' }"
>
<start-time-icon
:small="true"
v-if="!mergedOptions.hideDate"
:date="event.beginsOn.toString()"
/>
</div>
<span <span
class="text-gray-700 dark:text-white font-semibold hidden" class="text-gray-700 dark:text-white font-semibold hidden"
:class="{ 'sm:block': mode === 'row' }" :class="{ 'sm:block': mode === 'row' }"
@ -73,7 +83,7 @@
</h2> </h2>
<div class=""> <div class="">
<div <div
class="flex items-center text-violet-3 dark:text-white" class="bg-fomo-blue flex items-center text-violet-3 dark:text-white"
dir="auto" dir="auto"
> >
<figure class="" v-if="actorAvatarURL"> <figure class="" v-if="actorAvatarURL">
@ -91,7 +101,7 @@
{{ organizerDisplayName(event) }} {{ organizerDisplayName(event) }}
</span> </span>
</div> </div>
<inline-address <inline-address class="bg-fomo-purple"
v-if="event.physicalAddress" v-if="event.physicalAddress"
:physical-address="event.physicalAddress" :physical-address="event.physicalAddress"
/> />
@ -161,6 +171,7 @@ import {
organizerAvatarUrl, organizerAvatarUrl,
} from "@/types/event.model"; } from "@/types/event.model";
import DateCalendarIcon from "@/components/Event/DateCalendarIcon.vue"; import DateCalendarIcon from "@/components/Event/DateCalendarIcon.vue";
import StartTimeIcon from "@/components/Event/StartTimeIcon.vue";
import LazyImageWrapper from "@/components/Image/LazyImageWrapper.vue"; import LazyImageWrapper from "@/components/Image/LazyImageWrapper.vue";
import { EventStatus } from "@/types/enums"; import { EventStatus } from "@/types/enums";
import RouteName from "../../router/name"; import RouteName from "../../router/name";

View file

@ -3,7 +3,7 @@
class="bg-white dark:bg-mbz-purple dark:hover:bg-mbz-purple-400 mb-5 mt-4 pb-2 md:p-0 rounded-t-lg" class="bg-white dark:bg-mbz-purple dark:hover:bg-mbz-purple-400 mb-5 mt-4 pb-2 md:p-0 rounded-t-lg"
> >
<div <div
class="bg-mbz-yellow-alt-100 flex p-2 text-violet-title rounded-t-lg" class="bg-fomo-blue flex p-2 text-violet-title rounded-t-lg"
dir="auto" dir="auto"
> >
<figure <figure

View file

@ -0,0 +1,53 @@
<template>
<div
class="starttime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-violet-3 dark:text-white"
:class="{ small }"
:style="`--small: ${smallStyle}`"
>
<div class="starttime-container-content font-semibold">
<Clock class="clock-icon"/><time :datetime="dateObj.toISOString()">{{
time
}}</time>
</div>
</div>
</template>
<script lang="ts" setup>
import { localeShortWeekDayNames } from "@/utils/datetime";
import { computed } from "vue";
import Clock from "vue-material-design-icons/ClockTimeTenOutline.vue";
const props = withDefaults(
defineProps<{
date: string;
small?: boolean;
}>(),
{ small: false }
);
const dateObj = computed<Date>(() => new Date(props.date));
const time = computed<string>(() =>
dateObj.value.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit" })
);
const smallStyle = computed<string>(() => (props.small ? "1.2" : "2"));
</script>
<style lang="scss" scoped>
div.starttime-container {
width: auto;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.2);
height: calc(40px * var(--small));
}
.starttime-container-content {
font-size: calc(1rem * var(--small));
padding: 0 0.5rem;
}
.clock-icon {
vertical-align: middle;
padding-right: 0.2rem;
display: inline-block;
}
</style>

View file

@ -3,10 +3,10 @@
class="flex flex-col mb-3 border-2" class="flex flex-col mb-3 border-2"
:class="{ :class="{
'border-mbz-purple': privateSection, 'border-mbz-purple': privateSection,
'border-yellow-1': !privateSection, 'border-fomo-blue': !privateSection,
}" }"
> >
<div class="flex items-stretch py-3 px-1 bg-yellow-1 text-violet-title"> <div class="flex items-stretch py-3 px-1 bg-fomo-blue text-violet-title">
<div class="flex flex-1 gap-1"> <div class="flex flex-1 gap-1">
<o-icon :icon="icon" custom-size="36" /> <o-icon :icon="icon" custom-size="36" />
<h2 class="text-2xl font-medium mt-0">{{ title }}</h2> <h2 class="text-2xl font-medium mt-0">{{ title }}</h2>

View file

@ -19,31 +19,29 @@
</div> </div>
<slot name="subtitle" /> <slot name="subtitle" />
</div> </div>
<div class="" v-show="showScrollLeftButton"> <!-- <div class="hidden sm:block" v-show="showScrollLeftButton">
<button <button
@click="scrollLeft" @click="scrollLeft"
class="absolute inset-y-0 my-auto z-10 rounded-full bg-white dark:bg-transparent w-10 h-10 border border-shadowColor -left-5 ml-2" class="absolute inset-y-0 my-auto z-10 rounded-full bg-white dark:bg-transparent w-10 h-10 border border-shadowColor -left-5 ml-2"
> >
<span class="">&lt;</span> <span class="">&lt;</span>
</button> </button>
</div> </div> -->
<div class="overflow-hidden"> <div class="overflow-hidden">
<div <div
class="relative w-full snap-x snap-always snap-mandatory overflow-x-auto flex pb-6 gap-x-5 gap-y-8 p-1" class="multi-card-event"
ref="scrollContainer"
@scroll="scrollHandler"
> >
<slot name="content" /> <slot name="content" />
</div> </div>
</div> </div>
<div class="" v-show="showScrollRightButton"> <!-- <div class="hidden sm:block" v-show="showScrollRightButton">
<button <button
@click="scrollRight" @click="scrollRight"
class="absolute inset-y-0 my-auto z-10 rounded-full bg-white dark:bg-transparent w-10 h-10 border border-shadowColor -right-5 mr-2" class="absolute inset-y-0 my-auto z-10 rounded-full bg-white dark:bg-transparent w-10 h-10 border border-shadowColor -right-5"
> >
<span class="">&gt;</span> <span class="">&gt;</span>
</button> </button>
</div> </div> -->
</div> </div>
</template> </template>
@ -63,56 +61,69 @@ const emit = defineEmits(["doGeoLoc"]);
const { t } = useI18n({ useScope: "global" }); const { t } = useI18n({ useScope: "global" });
const showScrollRightButton = ref(false); // const showScrollRightButton = ref(true);
const showScrollLeftButton = ref(false); // const showScrollLeftButton = ref(false);
const scrollContainer = ref<any>(); // const scrollContainer = ref<any>();
const scrollHandler = () => { // const scrollHandler = () => {
if (scrollContainer.value) { // if (scrollContainer.value) {
showScrollRightButton.value = // showScrollRightButton.value =
scrollContainer.value.scrollLeft < // scrollContainer.value.scrollLeft <
scrollContainer.value.scrollWidth - scrollContainer.value.clientWidth; // scrollContainer.value.scrollWidth - scrollContainer.value.clientWidth;
showScrollLeftButton.value = scrollContainer.value.scrollLeft > 0; // showScrollLeftButton.value = scrollContainer.value.scrollLeft > 0;
} // }
}; // };
const doScroll = (e: Event, left: number) => { // const doScroll = (e: Event, left: number) => {
e.preventDefault(); // e.preventDefault();
if (scrollContainer.value) { // if (scrollContainer.value) {
scrollContainer.value.scrollBy({ // scrollContainer.value.scrollBy({
left, // left,
behavior: "smooth", // behavior: "smooth",
}); // });
} // }
}; // };
const scrollLeft = (e: Event) => { // const scrollLeft = (e: Event) => {
doScroll(e, -300); // doScroll(e, -300);
}; // };
const scrollRight = (e: Event) => { // const scrollRight = (e: Event) => {
doScroll(e, 300); // doScroll(e, 300);
}; // };
const scrollHorizontalToVertical = (evt: WheelEvent) => { // const scrollHorizontalToVertical = (evt: WheelEvent) => {
evt.deltaY > 0 ? doScroll(evt, 300) : doScroll(evt, -300); // evt.deltaY > 0 ? doScroll(evt, 300) : doScroll(evt, -300);
}; // };
onMounted(async () => { // onMounted(async () => {
// Make sure everything is mounted properly // scrollContainer.value.addEventListener("wheel", scrollHorizontalToVertical);
setTimeout(() => { // });
scrollHandler();
}, 1500);
scrollContainer.value.addEventListener("wheel", scrollHorizontalToVertical);
});
onUnmounted(() => { // onUnmounted(() => {
if (scrollContainer.value) { // if (scrollContainer.value) {
scrollContainer.value.removeEventListener( // scrollContainer.value.removeEventListener(
"wheel", // "wheel",
scrollHorizontalToVertical // scrollHorizontalToVertical
); // );
} // }
}); // });
</script> </script>
<style lang="scss" scoped>
.multi-card-event {
display: grid;
grid-auto-rows: 1fr;
grid-column-gap: 20px;
grid-row-gap: 30px;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
margin-bottom: 2rem;
.event-card {
height: 100%;
display: flex;
flex-direction: column;
}
}
</style>

View file

@ -0,0 +1,78 @@
<template>
<close-content
class="container mx-auto px-2"
v-show="loadingEvents || (events && events.total > 0)"
:suggestGeoloc="false"
v-on="attrs"
>
<template #title>
{{ t("Upcoming events") }}
</template>
<template #subtitle>
<i18n-t
class="text-slate-700 dark:text-slate-300"
tag="p"
keypath="On {instance} and other federated instances"
>
<template #instance>
<b>{{ instanceName }}</b>
</template>
</i18n-t>
</template>
<template #content>
<skeleton-event-result
v-for="i in 6"
class="scroll-ml-6 snap-center shrink-0 w-[18rem] my-4"
:key="i"
v-show="loadingEvents"
/>
<event-card
v-for="event in events.elements"
:event="event"
:key="event.uuid"
/>
<more-content
:to="{
name: RouteName.SEARCH,
query: {
contentType: 'EVENTS',
},
}"
>
{{ t("View more events") }}
</more-content>
</template>
</close-content>
</template>
<script lang="ts" setup>
import MoreContent from "./MoreContent.vue";
import CloseContent from "./CloseContent.vue";
import { computed, useAttrs } from "vue";
import { IEvent } from "@/types/event.model";
import { useQuery } from "@vue/apollo-composable";
import EventCard from "../Event/EventCard.vue";
import { Paginate } from "@/types/paginate";
import SkeletonEventResult from "../Event/SkeletonEventResult.vue";
import { EventSortField, SortDirection } from "@/types/enums";
import { FETCH_EVENTS } from "@/graphql/event";
import { useI18n } from "vue-i18n";
import RouteName from "@/router/name";
defineProps<{
instanceName: string;
}>();
const { t } = useI18n({ useScope: "global" });
const attrs = useAttrs();
const { result: resultEvents, loading: loadingEvents } = useQuery<{
events: Paginate<IEvent>;
}>(FETCH_EVENTS, {
orderBy: EventSortField.BEGINS_ON,
direction: SortDirection.ASC,
});
const events = computed(
() => resultEvents.value?.events ?? { total: 0, elements: [] }
);
</script>

View file

@ -1,42 +1,31 @@
<template> <template>
<svg <svg
class="bg-white dark:bg-zinc-900 dark:fill-white"
:class="{ 'bg-gray-900': invert }"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 248.16 46.78" viewBox="0 0 248.16 46.78"
> >
<title>Mobilizon Logo</title> <title>Fomo Logo</title>
<g data-name="header"> <g data-name="header">
<path <path
d="M0 45.82l3.18-40.8a29.88 29.88 0 015.07-.36 27.74 27.74 0 014.95.36l4.86 17.16a92.19 92.19 0 012.34 10.08h.36a92.19 92.19 0 012.34-10.08L28 5.02a29.23 29.23 0 015-.36 29.23 29.23 0 015 .36l3.18 40.8a13.61 13.61 0 01-3.63.42 23.41 23.41 0 01-3.63-.24l-1.2-19.92q-.36-5.52-.48-12.84h-.44l-7.32 26.51a25.62 25.62 0 01-4 .3 23.36 23.36 0 01-3.84-.3L9.36 13.24H9q-.3 8.94-.48 12.84L7.26 46a22.47 22.47 0 01-3.6.24A13.75 13.75 0 010 45.82zM74 31.06q0 8-4.26 12.3a12.21 12.21 0 01-9 3.42 12.21 12.21 0 01-9-3.42q-4.26-4.26-4.26-12.3t4.24-12.31a12.21 12.21 0 019-3.42 12.21 12.21 0 019 3.42Q74 23.02 74 31.06zM60.75 20.98q-5.67 0-5.67 10.08t5.67 10.08q5.67 0 5.67-10.08t-5.67-10.08zM103.2 19.75q2.7 4.11 2.7 11.28T102 42.31a13.18 13.18 0 01-10 4.11 31.41 31.41 0 01-11.34-2V2.2l.4-.45h2.76A4 4 0 0187 2.83a5.38 5.38 0 01.93 3.57v11.94a12.08 12.08 0 017.56-2.7 8.71 8.71 0 017.71 4.11zm-9.72 2a7.28 7.28 0 00-5.58 2.82v16a15 15 0 004.08.54 5.25 5.25 0 004.68-2.67q1.68-2.67 1.68-7.59 0-9.03-4.86-9.1zM121 22v23.94a20.85 20.85 0 01-3.66.3 23 23 0 01-3.78-.3V24.75q0-3.24-2.7-3.24h-.72a9.32 9.32 0 01-.3-2.58 10.7 10.7 0 01.3-2.7 39.63 39.63 0 014.38-.24h1a5.19 5.19 0 014 1.62A6.27 6.27 0 01121 22z" d="M 62.099803,46.107167 H 61.977828 L 56.44017,42.887031 q -0.170765,-0.09758 -0.170765,-0.292739 L 56.171825,11.905419 Q 56.19622,11.734654 56.34259,11.637074 75.248692,0.70812735 75.346272,0.70812735 q 0.09758,0 5.659633,3.24453105 l 0.04879,0.04879 0.04879,0.024395 v 0.024395 h 0.02439 l 0.04879,0.09758 0.02439,3.7080355 Q 81.176669,8.0510134 81.0303,8.1485933 L 65.490704,17.101547 v 2.805422 q 9.806778,-5.659633 9.904357,-5.659633 0.07318,0 2.878607,1.634463 2.805422,1.610068 2.805422,1.634463 h 0.0244 v 0.02439 q 0.02439,0.0244 0.02439,0.04879 0.02439,0 0.02439,0 0.02439,0 0.02439,0.0244 l 0.02439,0.121975 h 0.02439 v 3.659245 q 0,0.170765 -0.170764,0.268345 l -15.515202,8.977349 0.0244,13.344049 q 0,0.170765 -0.170764,0.268344 -3.171347,1.854018 -3.293321,1.854018 z m 3.415295,-19.833111 14.710168,-8.489449 -4.830205,-2.829817 -9.879963,5.708423 z m -3.756825,18.930497 -0.07319,-29.883838 -4.830204,-2.829817 0.07319,29.908234 z M 62.002223,14.735235 80.176476,4.2453981 75.346272,1.4399765 57.172019,11.929814 Z m 0.414714,30.469318 2.488287,-1.414908 -0.04879,-13.344049 q 0.0244,-0.19516 0.170765,-0.292739 l 15.539596,-8.952955 v -2.854211 q -15.295646,8.830979 -15.368831,8.830979 -0.317135,0 -0.34153,-0.341529 l -0.02439,-9.928753 q 0,-0.170765 0.170765,-0.268345 L 80.518005,7.6606939 V 4.8308773 L 62.343752,15.320715 Z"
stroke="#ffffff"
stroke-opacity="1"
/> />
<path <path
d="M119.82.84a7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.93 7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.93z" d="m 98.667864,46.107167 q -0.09758,0 -0.09758,-0.02439 h -0.04879 l -5.513264,-3.220136 q -0.146369,-0.09758 -0.170764,-0.268344 l -0.07319,-30.688873 q 0.0244,-0.170765 0.170764,-0.268345 18.906104,-10.92894665 19.003684,-10.92894665 0.0732,0 2.8786,1.63446305 l 2.80543,1.634463 h 0.0244 v 0.024395 h 0.0244 v 0.024395 h 0.0244 l 0.0244,0.04879 v 0.024395 q 0.0244,0.09758 0.0244,0.09758 0.0244,0 0.0244,0.024395 l 0.0732,30.6888729 q 0,0.19516 -0.17076,0.292739 Q 98.789839,46.107167 98.667864,46.107167 Z M 98.35073,45.204553 98.25315,15.320715 93.422946,12.490898 93.520526,42.399132 Z M 98.59468,14.735235 116.76893,4.2453981 111.93873,1.4399765 93.764475,11.929814 Z M 99.009394,45.204553 117.18365,34.714716 117.11046,4.8064824 98.936209,15.320715 Z m 2.805426,-4.513069 q -0.34153,0 -0.34153,-0.317135 l -0.0732,-23.467961 q 0.0244,-0.170765 0.17077,-0.268345 12.6122,-7.3184911 12.73417,-7.3184911 0.31714,0 0.31714,0.3415296 l 0.0732,23.4923565 q -0.0244,0.14637 -0.17076,0.24395 -12.6122,7.294096 -12.70978,7.294096 z m 0.31713,-7.269701 6.39148,-3.708036 -0.0488,-16.320235 -6.39148,3.708035 z m 0,6.367087 11.56322,-6.684222 -4.83021,-2.805422 -6.73301,3.903196 z m 11.90475,-7.245306 -0.0732,-22.297003 -4.80581,2.781026 0.0488,16.68616 z"
fill="currentColor" stroke="#ffffff"
stroke-opacity="1"
/> />
<path <path
d="M139.08 40.42h2a10.23 10.23 0 01.6 3.18 9.24 9.24 0 01-.18 2.1 38.47 38.47 0 01-5.64.54q-6.48 0-6.48-7v-37l.36-.42h2.88a3.94 3.94 0 013.12 1.05 5.52 5.52 0 01.9 3.57v31.31q-.02 2.67 2.44 2.67zM155.94 22v23.94a20.85 20.85 0 01-3.66.3 23 23 0 01-3.78-.3V24.75q0-3.24-2.7-3.24h-.72a9.32 9.32 0 01-.3-2.58 10.7 10.7 0 01.3-2.7 39.63 39.63 0 014.38-.24h1a5.19 5.19 0 014.05 1.62 6.27 6.27 0 011.43 4.39z" d="m 135.28472,46.107167 q -0.12198,0 -0.12198,-0.02439 h -0.0488 l -5.51326,-3.220136 q -0.14637,-0.09758 -0.17077,-0.268344 l -0.0732,-30.688873 q 0.0244,-0.170765 0.17076,-0.268345 18.90611,-10.92894665 19.00369,-10.92894665 0.0732,0 2.903,1.63446305 l 2.80542,1.634463 v 0.024395 h 0.0244 v 0.024395 h 0.0244 l 0.0244,0.04879 0.0488,0.1463698 0.0732,30.6888729 q 0,0.19516 -0.14637,0.292739 -3.19574,1.829623 -3.24453,1.854018 -0.0244,0 -0.0732,0 l -0.12197,-0.02439 -4.26912,-2.488287 0.0244,4.903389 q -0.0244,0.170765 -0.17076,0.268345 -3.19574,1.854018 -3.24453,1.878413 -0.0244,0 -0.0732,0 -0.0488,0 -0.0976,0 -0.0244,-0.0244 -0.0488,-0.04879 l -4.24472,-2.463892 0.0244,4.878994 q 0,0.19516 -0.17076,0.292739 -3.19574,1.854018 -3.29332,1.854018 z m -0.34153,-0.902614 -0.0976,-29.883838 -4.83021,-2.829817 0.0976,29.908234 z m 0.24395,-30.469318 18.17425,-10.4898369 -4.8302,-2.8054216 -18.17426,10.4898375 z m 7.61123,25.931854 -0.0732,-25.907459 -4.04956,2.341917 0.0488,21.223625 z m 7.83078,-4.51307 -0.0732,-25.907458 -4.04957,2.317522 0.0732,21.223624 z m -15.0273,9.050534 2.48829,-1.414908 -0.0732,-26.883257 q 0,-0.170765 0.14637,-0.29274 4.78142,-2.756632 4.879,-2.756632 0.34153,0 0.34153,0.34153 l 0.0732,26.468543 2.46389,-1.414908 v -5.269314 l -0.0732,-21.589549 q 0,-0.19516 0.17076,-0.292739 4.78142,-2.7810271 4.879,-2.7810271 0.31713,0 0.31713,0.3415296 l 0.0976,26.4929375 2.46389,-1.439303 -0.0732,-29.9082336 -18.17425,10.5142326 z"
stroke="#ffffff"
stroke-opacity="1"
/> />
<path <path
d="M154.8 2.84a7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.93 7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.93z" d="m 171.85278,46.107167 q -0.0976,0 -0.0976,-0.02439 h -0.0488 l -5.51326,-3.220136 q -0.14637,-0.09758 -0.17077,-0.268344 l -0.0732,-30.688873 q 0.0244,-0.170765 0.17076,-0.268345 18.90611,-10.92894665 19.00369,-10.92894665 0.0732,0 2.8786,1.63446305 l 2.80542,1.634463 h 0.0244 v 0.024395 h 0.0244 v 0.024395 h 0.0244 l 0.0244,0.04879 v 0.024395 q 0.0244,0.09758 0.0244,0.09758 0.0244,0 0.0244,0.024395 l 0.0732,30.6888729 q 0,0.19516 -0.17077,0.292739 -18.8817,10.904552 -19.00368,10.904552 z m -0.31713,-0.902614 -0.0976,-29.883838 -4.83021,-2.829817 0.0976,29.908234 z M 171.7796,14.735235 189.95385,4.2453981 185.12365,1.4399765 166.94939,11.929814 Z m 0.41471,30.469318 18.17425,-10.489837 -0.0732,-29.9082336 -18.17425,10.5142326 z m 2.80542,-4.513069 q -0.34153,0 -0.34153,-0.317135 l -0.0732,-23.467961 q 0.0244,-0.170765 0.17076,-0.268345 12.6122,-7.3184911 12.73418,-7.3184911 0.31713,0 0.31713,0.3415296 l 0.0732,23.4923565 q -0.0244,0.14637 -0.17077,0.24395 -12.6122,7.294096 -12.70978,7.294096 z m 0.31714,-7.269701 6.39148,-3.708036 -0.0488,-16.320235 -6.39148,3.708035 z m 0,6.367087 11.56321,-6.684222 -4.8302,-2.805422 -6.73301,3.903196 z m 11.90474,-7.245306 -0.0732,-22.297003 -4.80581,2.781026 0.0488,16.68616 z"
fill="currentColor" stroke="#ffffff"
/> stroke-opacity="1"
<path
d="M163.08 39.22l8.76-11.82q1.32-1.8 4.8-5.7l-.18-.3a63.09 63.09 0 01-7.74.42H163a9.79 9.79 0 01-.24-2.34 15.8 15.8 0 01.42-3.3h20.4a16.31 16.31 0 011 4.26 4.1 4.1 0 01-.78 2.34L175 34.66a64.65 64.65 0 01-4.56 5.7l.18.24q3.12-.3 5.22-.3h2.58a15.35 15.35 0 006.12-.9 9.4 9.4 0 01.72 3.12q0 3.42-4.32 3.42h-18a14.27 14.27 0 01-.9-3.93 5.08 5.08 0 011.04-2.79zM215.88 31.06q0 8-4.26 12.3a13.63 13.63 0 01-18.06 0q-4.26-4.26-4.26-12.3t4.26-12.31a13.63 13.63 0 0118.06 0q4.26 4.27 4.26 12.31zm-13.29-10.08q-5.67 0-5.67 10.08t5.67 10.08q5.67 0 5.67-10.08t-5.67-10.08zM247 25.84v13.32a11 11 0 001.2 5.64 7 7 0 01-4.41 1.56q-2.43 0-3.33-1.14a5.69 5.69 0 01-.9-3.54V27.4a7.74 7.74 0 00-.72-3.87 2.78 2.78 0 00-2.58-1.17 8.62 8.62 0 00-6.3 3v20.58a20.85 20.85 0 01-3.66.3 23 23 0 01-3.78-.3v-29.7l.42-.36h2.76q3.42 0 4.08 3.6 4.38-3.84 8.73-3.84t6.42 2.82a12.17 12.17 0 012.07 7.38z"
/>
<path
d="M57.26 10.75a7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.84 7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.84zM198.26 10.75a7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.84 7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.84z"
fill="currentColor"
/> />
</g> </g>
</svg> </svg>
</template> </template>
<script lang="ts" setup>
withDefaults(
defineProps<{
invert?: boolean;
}>(),
{ invert: false }
);
</script>

View file

@ -1,6 +1,6 @@
<template> <template>
<nav <nav
class="bg-white border-gray-200 px-2 sm:px-4 py-2.5 dark:bg-zinc-900" class="bg-zinc-900 border-gray-200 px-2 sm:px-4 py-2.5"
id="navbar" id="navbar"
> >
<div <div
@ -18,7 +18,7 @@
<template #trigger> <template #trigger>
<button <button
type="button" type="button"
class="flex sm:mr-3 text-sm rounded-full md:mr-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600" class="flex sm:mr-3 text-sm rounded-full md:mr-0 focus:ring-4 focus:ring-gray-600"
id="user-menu-button" id="user-menu-button"
aria-expanded="false" aria-expanded="false"
> >
@ -33,10 +33,11 @@
loading="lazy" loading="lazy"
/> />
</figure> </figure>
<AccountCircle v-else :size="32" /> <AccountCircle style="color:white" v-else :size="32" />
</button> </button>
</template> </template>
<!-- Dropdown menu --> <!-- Dropdown menu -->
<div <div
class="z-50 text-base list-none bg-white rounded divide-y divide-gray-100 dark:bg-zinc-700 dark:divide-gray-600 max-w-xs" class="z-50 text-base list-none bg-white rounded divide-y divide-gray-100 dark:bg-zinc-700 dark:divide-gray-600 max-w-xs"
@ -167,28 +168,28 @@
<li v-if="currentActor?.id"> <li v-if="currentActor?.id">
<router-link <router-link
:to="{ name: RouteName.MY_EVENTS }" :to="{ name: RouteName.MY_EVENTS }"
class="block py-2 pr-4 pl-3 text-zinc-700 border-b border-gray-100 hover:bg-zinc-50 md:hover:bg-transparent md:border-0 md:hover:text-mbz-purple-700 md:p-0 dark:text-zinc-400 md:dark:hover:text-white dark:hover:bg-zinc-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700" class="block py-2 pr-4 pl-3 border-b md:hover:bg-transparent md:border-0 md:hover:text-mbz-purple-700 md:p-0 text-zinc-400 md:dark:hover:text-white hover:bg-zinc-700 hover:text-white md:dark:hover:bg-transparent border-gray-700"
>{{ t("My events") }}</router-link >{{ t("My events") }}</router-link
> >
</li> </li>
<li v-if="currentActor?.id"> <li v-if="currentActor?.id">
<router-link <router-link
:to="{ name: RouteName.MY_GROUPS }" :to="{ name: RouteName.MY_GROUPS }"
class="block py-2 pr-4 pl-3 text-zinc-700 border-b border-gray-100 hover:bg-zinc-50 md:hover:bg-transparent md:border-0 md:hover:text-mbz-purple-700 md:p-0 dark:text-zinc-400 md:dark:hover:text-white dark:hover:bg-zinc-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700" class="block py-2 pr-4 pl-3 border-b md:hover:bg-transparent md:border-0 md:hover:text-mbz-purple-700 md:p-0 text-zinc-400 md:dark:hover:text-white hover:bg-zinc-700 hover:text-white md:dark:hover:bg-transparent border-gray-700"
>{{ t("My groups") }}</router-link >{{ t("My groups") }}</router-link
> >
</li> </li>
<li v-if="!currentActor?.id"> <li v-if="!currentActor?.id">
<router-link <router-link
:to="{ name: RouteName.LOGIN }" :to="{ name: RouteName.LOGIN }"
class="block py-2 pr-4 pl-3 text-zinc-700 border-b border-gray-100 hover:bg-zinc-50 md:hover:bg-transparent md:border-0 md:hover:text-mbz-purple-700 md:p-0 dark:text-zinc-400 md:dark:hover:text-white dark:hover:bg-zinc-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700" class="block py-2 pr-4 pl-3 border-b md:hover:bg-transparent md:border-0 md:hover:text-mbz-purple-700 md:p-0 text-zinc-400 md:dark:hover:text-white hover:bg-zinc-700 hover:text-white md:dark:hover:bg-transparent border-gray-700"
>{{ t("Login") }}</router-link >{{ t("Login") }}</router-link
> >
</li> </li>
<li v-if="!currentActor?.id && canRegister"> <li v-if="!currentActor?.id && canRegister">
<router-link <router-link
:to="{ name: RouteName.REGISTER }" :to="{ name: RouteName.REGISTER }"
class="block py-2 pr-4 pl-3 text-zinc-700 border-b border-gray-100 hover:bg-zinc-50 md:hover:bg-transparent md:border-0 md:hover:text-mbz-purple-700 md:p-0 dark:text-zinc-400 md:dark:hover:text-white dark:hover:bg-zinc-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700" class="block py-2 pr-4 pl-3 border-b md:hover:bg-transparent md:border-0 md:hover:text-mbz-purple-700 md:p-0 text-zinc-400 md:dark:hover:text-white hover:bg-zinc-700 hover:text-white md:dark:hover:bg-transparent border-gray-700"
>{{ t("Register") }}</router-link >{{ t("Register") }}</router-link
> >
</li> </li>

View file

@ -1,23 +1,10 @@
<template> <template>
<footer <footer
class="bg-violet-2 color-secondary flex flex-col items-center py-2 px-3" class="bg-zinc-900 color-secondary flex flex-col items-center py-2 px-3"
ref="footer" ref="footer"
> >
<picture class="flex max-w-xl">
<source
:srcset="`/img/pics/footer_${random}-1024w.webp 1x, /img/pics/footer_${random}-1920w.webp 2x`"
type="image/webp"
/>
<img
:src="`/img/pics/footer_${random}-1024w.webp`"
alt=""
width="1024"
height="428"
loading="lazy"
/>
</picture>
<ul <ul
class="inline-flex flex-wrap justify-around gap-3 text-lg text-white underline decoration-yellow-1" class="inline-flex flex-wrap justify-around gap-3 text-lg text-white underline decoration-fomo-blue"
> >
<li> <li>
<o-select <o-select
@ -59,7 +46,7 @@
<a href="#navbar">{{ t("Back to top") }}</a> <a href="#navbar">{{ t("Back to top") }}</a>
</li> </li>
</ul> </ul>
<div class="text-center flex-1 pt-2 text-yellow-1"> <div class="text-center flex-1 pt-2 text-fomo-blue">
<i18n-t <i18n-t
tag="span" tag="span"
keypath="Powered by {mobilizon}. © 2018 - {date} The Mobilizon Contributors - Made with the financial support of {contributors}." keypath="Powered by {mobilizon}. © 2018 - {date} The Mobilizon Contributors - Made with the financial support of {contributors}."
@ -67,7 +54,7 @@
<template #mobilizon> <template #mobilizon>
<a <a
rel="external" rel="external"
class="text-white underline decoration-yellow-1" class="text-white underline decoration-fomo-blue"
href="https://joinmobilizon.org" href="https://joinmobilizon.org"
>{{ t("Mobilizon") }}</a >{{ t("Mobilizon") }}</a
> >
@ -78,7 +65,7 @@
<template #contributors> <template #contributors>
<a <a
rel="external" rel="external"
class="text-white underline decoration-yellow-1" class="text-white underline decoration-fomo-blue"
href="https://joinmobilizon.org/hall-of-fame" href="https://joinmobilizon.org/hall-of-fame"
>{{ t("more than 1360 contributors") }}</a >{{ t("more than 1360 contributors") }}</a
> >

View file

@ -1,6 +1,6 @@
<template> <template>
<div <div
class="bg-mbz-yellow-alt-50 hover:bg-mbz-yellow-alt-100 dark:bg-zinc-700 hover:dark:bg-zinc-600 rounded" class="bg-mbz-yellow-alt-50 hover:bg-fomo-blue dark:bg-zinc-700 hover:dark:bg-zinc-600 rounded"
v-if="report" v-if="report"
> >
<div class="flex justify-between gap-1 border-b p-2"> <div class="flex justify-between gap-1 border-b p-2">

View file

@ -3,7 +3,7 @@
class="setting-menu-item" class="setting-menu-item"
:class="{ :class="{
'cursor-pointer bg-mbz-yellow-alt-500 dark:bg-mbz-purple-500': isActive, 'cursor-pointer bg-mbz-yellow-alt-500 dark:bg-mbz-purple-500': isActive,
'bg-mbz-yellow-alt-100 hover:bg-mbz-yellow-alt-200 dark:bg-mbz-purple-300 dark:hover:bg-mbz-purple-400 dark:text-white': 'bg-fomo-blue hover:bg-mbz-yellow-alt-200 dark:bg-mbz-purple-300 dark:hover:bg-mbz-purple-400 dark:text-white':
!isActive, !isActive,
}" }"
> >

View file

@ -30,7 +30,7 @@ const typeClasses = computed(() => {
case "info": case "info":
return "bg-mbz-info dark:text-black"; return "bg-mbz-info dark:text-black";
case "warning": case "warning":
return "bg-yellow-1"; return "bg-fomo-blue";
case "danger": case "danger":
return "bg-mbz-danger dark:text-white"; return "bg-mbz-danger dark:text-white";
} }

4
js/src/extension.ts Normal file
View file

@ -0,0 +1,4 @@
export const Images = {
appLogo: "/src/assets/images/default_logo.svg"
};

View file

@ -0,0 +1,20 @@
<template>
<div v-html="svg"/>
</template>
<script lang="ts">
export default {
props: ['src'],
data() {
return {
svg: ""
}
},
async created() {
const svgImport = await import(this.$props.src + '?raw');
this.svg = svgImport.default;
}
}
</script>

View file

@ -16,7 +16,7 @@
"A cookie is a small file containing information that is sent to your computer when you visit a website. When you visit the site again, the cookie allows that site to recognize your browser. Cookies may store user preferences and other information. You can configure your browser to refuse all cookies. However, this may result in some website features or services partially working. Local storage works the same way but allows you to store more data.": "Kolačić je mala datoteka koja sadrži sve informacije poslane vašem računalu kada posjetite stranicu. Kada ju opet posjetite, kolačić omogućuje stranici da prepozna vaš preglednik. Kolačić može sadržavati vaše postavke ili druge informacije. Možete postaviti svoj preglednik da blokira sve kolačiće, ali to može dovesti do djelomičnog kvara nekih funkcija stranice. Lokalno spremište radi na isti način ali vam dopušta da spremite više podataka.", "A cookie is a small file containing information that is sent to your computer when you visit a website. When you visit the site again, the cookie allows that site to recognize your browser. Cookies may store user preferences and other information. You can configure your browser to refuse all cookies. However, this may result in some website features or services partially working. Local storage works the same way but allows you to store more data.": "Kolačić je mala datoteka koja sadrži sve informacije poslane vašem računalu kada posjetite stranicu. Kada ju opet posjetite, kolačić omogućuje stranici da prepozna vaš preglednik. Kolačić može sadržavati vaše postavke ili druge informacije. Možete postaviti svoj preglednik da blokira sve kolačiće, ali to može dovesti do djelomičnog kvara nekih funkcija stranice. Lokalno spremište radi na isti način ali vam dopušta da spremite više podataka.",
"A discussion has been created or updated": "Jedna diskusija je stvorena ili aktualizirana", "A discussion has been created or updated": "Jedna diskusija je stvorena ili aktualizirana",
"A federated software": "Federaliziran softver", "A federated software": "Federaliziran softver",
"A fediverse account URL to follow for event updates": "", "A fediverse account URL to follow for event updates": "URL Fediverse računa za praćenje aktualiziranja događaja",
"A few lines about your group": "Par redaka o tvojoj grupi", "A few lines about your group": "Par redaka o tvojoj grupi",
"A link to a page presenting the event schedule": "Poveznica na stranicu s rasporedom događaja", "A link to a page presenting the event schedule": "Poveznica na stranicu s rasporedom događaja",
"A link to a page presenting the price options": "Poveznica na stranicu sa cijenama", "A link to a page presenting the price options": "Poveznica na stranicu sa cijenama",
@ -32,7 +32,7 @@
"A practical tool": "Praktični alat", "A practical tool": "Praktični alat",
"A resource has been created or updated": "Jedan resurs je stvoren ili aktualiziran", "A resource has been created or updated": "Jedan resurs je stvoren ili aktualiziran",
"A short tagline for your instance homepage. Defaults to \"Gather ⋅ Organize ⋅ Mobilize\"": "Kartki slogan za naslovnu stranicu instance. Zadan je na \"Skupi ⋅ Organiziraj ⋅ Mobiliziraj\"", "A short tagline for your instance homepage. Defaults to \"Gather ⋅ Organize ⋅ Mobilize\"": "Kartki slogan za naslovnu stranicu instance. Zadan je na \"Skupi ⋅ Organiziraj ⋅ Mobiliziraj\"",
"A twitter account handle to follow for event updates": "", "A twitter account handle to follow for event updates": "Twitter račun za praćenje aktualiziranja događaja",
"A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Emancipacijski i etični alat za okupljanje, organiziranje, i mobiliziranje, sa prijateljskim korisničkim sučeljem.", "A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Emancipacijski i etični alat za okupljanje, organiziranje, i mobiliziranje, sa prijateljskim korisničkim sučeljem.",
"A validation email was sent to {email}": "E-mail za ovjeru je poslan na {email}", "A validation email was sent to {email}": "E-mail za ovjeru je poslan na {email}",
"API": "API", "API": "API",
@ -86,7 +86,7 @@
"All the places have already been taken": "Sva mjesta su već zauzeta", "All the places have already been taken": "Sva mjesta su već zauzeta",
"Allow all comments from users with accounts": "Dozvoli sve komentare prijavljenih korisnika", "Allow all comments from users with accounts": "Dozvoli sve komentare prijavljenih korisnika",
"Allow registrations": "Dozvoli registracije", "Allow registrations": "Dozvoli registracije",
"An URL to an external ticketing platform": "", "An URL to an external ticketing platform": "URL-adresa eksterne platforme za prodaju karata",
"An error has occured while refreshing the page.": "Dogodila se greška prilikom aktualiziranja stranice.", "An error has occured while refreshing the page.": "Dogodila se greška prilikom aktualiziranja stranice.",
"An error has occured. Sorry about that. You may try to reload the page.": "Desila se greška! Isprike. Možete probati ponovno učitati stranicu.", "An error has occured. Sorry about that. You may try to reload the page.": "Desila se greška! Isprike. Možete probati ponovno učitati stranicu.",
"An ethical alternative": "Etična alternativa", "An ethical alternative": "Etična alternativa",
@ -98,6 +98,7 @@
"An event from one of my groups has been published": "Događaj jedne od mojih grupa je objavljen", "An event from one of my groups has been published": "Događaj jedne od mojih grupa je objavljen",
"An event from one of my groups has been updated or deleted": "Događaj jedne od mojih grupa je aktualiziran ili izbrisan", "An event from one of my groups has been updated or deleted": "Događaj jedne od mojih grupa je aktualiziran ili izbrisan",
"An instance is an installed version of the Mobilizon software running on a server. An instance can be run by anyone using the {mobilizon_software} or other federated apps, aka the “fediverse”. This instance's name is {instance_name}. Mobilizon is a federated network of multiple instances (just like email servers), users registered on different instances may communicate even though they didn't register on the same instance.": "Instanca je instalirana verzija Mobilizon softvera koja radi na serveru. Instancu može postaviti bilo tko, tko koristi {mobilizon_software} ili druge federalizirane aplikacije, poznato i kao „fediverse”. Ime ove instance je {instance_name}. Mobilizon je federalizirana mreža kaj se sastoji od više instanca (kao e-mail serveri) gdje korisnici, koji su registrirani na različitim instancama mogu komunicirati iako se ne nalaze na istoj instanci.", "An instance is an installed version of the Mobilizon software running on a server. An instance can be run by anyone using the {mobilizon_software} or other federated apps, aka the “fediverse”. This instance's name is {instance_name}. Mobilizon is a federated network of multiple instances (just like email servers), users registered on different instances may communicate even though they didn't register on the same instance.": "Instanca je instalirana verzija Mobilizon softvera koja radi na serveru. Instancu može postaviti bilo tko, tko koristi {mobilizon_software} ili druge federalizirane aplikacije, poznato i kao „fediverse”. Ime ove instance je {instance_name}. Mobilizon je federalizirana mreža kaj se sastoji od više instanca (kao e-mail serveri) gdje korisnici, koji su registrirani na različitim instancama mogu komunicirati iako se ne nalaze na istoj instanci.",
"An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events, automatically and remotely.": "„Sučelje za programiranje aplikacija” ili „API” je komunikacijski protokol koji omogućuje komponentama softvera da međusobno komuniciraju. Mobilizon API, na primjer, može dozvoliti softverskim alatima trećih strana da komuniciraju s Mobilizon instancama za izvođenje određenih radnji, kao što je objavljivanje događaja, automatski i na daljinski način.",
"And {number} comments": "I {number} komentara", "And {number} comments": "I {number} komentara",
"Announcements and mentions notifications are always sent straight away.": "Najave i obavijesti o spominjanjima uvijek se šalju odmah.", "Announcements and mentions notifications are always sent straight away.": "Najave i obavijesti o spominjanjima uvijek se šalju odmah.",
"Anonymous participant": "Anonimni sudionik", "Anonymous participant": "Anonimni sudionik",
@ -158,7 +159,7 @@
"Cancel": "Otkaži", "Cancel": "Otkaži",
"Cancel anonymous participation": "Otkaži anonimno sudjelovanje", "Cancel anonymous participation": "Otkaži anonimno sudjelovanje",
"Cancel creation": "Otkaži stvaranje", "Cancel creation": "Otkaži stvaranje",
"Cancel discussion title edition": "", "Cancel discussion title edition": "Prekini mijenjanje naslova diskusije",
"Cancel edition": "Otkaži uređivanje", "Cancel edition": "Otkaži uređivanje",
"Cancel follow request": "", "Cancel follow request": "",
"Cancel membership request": "", "Cancel membership request": "",
@ -297,7 +298,7 @@
"Do you really want to suspend this account? All of the user's profiles will be deleted.": "Stvarno želiš suspendirati ovaj račun? Svi korisnički profili će se izbrisati.", "Do you really want to suspend this account? All of the user's profiles will be deleted.": "Stvarno želiš suspendirati ovaj račun? Svi korisnički profili će se izbrisati.",
"Do you wish to {create_event} or {explore_events}?": "Želite li {create_event} ili {explore_event}?", "Do you wish to {create_event} or {explore_events}?": "Želite li {create_event} ili {explore_event}?",
"Do you wish to {create_group} or {explore_groups}?": "Želite li {create_group} ili {explore_groups}?", "Do you wish to {create_group} or {explore_groups}?": "Želite li {create_group} ili {explore_groups}?",
"Does the event needs to be confirmed later or is it cancelled?": "", "Does the event needs to be confirmed later or is it cancelled?": "Treba li događaj kasnije potvrditi ili je otkazan?",
"Domain": "Domena", "Domain": "Domena",
"Draft": "Skica", "Draft": "Skica",
"Drafts": "Skice", "Drafts": "Skice",
@ -684,7 +685,7 @@
"On {instance} and other federated instances": "Na {instance} i drugim federaliziranim instancama", "On {instance} and other federated instances": "Na {instance} i drugim federaliziranim instancama",
"Online": "Online", "Online": "Online",
"Online events": "Online događaji", "Online events": "Online događaji",
"Online ticketing": "", "Online ticketing": "Online prodaja karata",
"Only accessible through link": "Dostupno samo preko poveznice", "Only accessible through link": "Dostupno samo preko poveznice",
"Only accessible through link (private)": "Dostupno samo kroz poveznicu (privatno)", "Only accessible through link (private)": "Dostupno samo kroz poveznicu (privatno)",
"Only accessible to members of the group": "Dostupno samo članovima grupe", "Only accessible to members of the group": "Dostupno samo članovima grupe",
@ -1075,7 +1076,7 @@
"Upcoming events from your groups": "", "Upcoming events from your groups": "",
"Update": "Ažuriraj", "Update": "Ažuriraj",
"Update app": "Aktualiziraj program", "Update app": "Aktualiziraj program",
"Update discussion title": "", "Update discussion title": "Aktualiziraj naslov diskusije",
"Update event {name}": "Ažuriraj događaj {name}", "Update event {name}": "Ažuriraj događaj {name}",
"Update group": "Ažuriraj grupu", "Update group": "Ažuriraj grupu",
"Update my event": "Ažuriraj moj događaj", "Update my event": "Ažuriraj moj događaj",
@ -1136,7 +1137,7 @@
"Whether the event is accessible with a wheelchair": "Je li postoji pristup za osobe u invalidskim kolicima", "Whether the event is accessible with a wheelchair": "Je li postoji pristup za osobe u invalidskim kolicima",
"Whether the event is interpreted in sign language": "Je li se događaj prevodi na znakovni jezik", "Whether the event is interpreted in sign language": "Je li se događaj prevodi na znakovni jezik",
"Whether the event live video is subtitled": "Je li video događaja uživo titlovan", "Whether the event live video is subtitled": "Je li video događaja uživo titlovan",
"Who can post a comment?": "", "Who can post a comment?": "Tko smije komentirati?",
"Who can view this event and participate": "Tko može vidjeti ovaj događaj i sudjelovati", "Who can view this event and participate": "Tko može vidjeti ovaj događaj i sudjelovati",
"Who can view this post": "Tko može vidjeti ovu objavu", "Who can view this post": "Tko može vidjeti ovu objavu",
"Who published {number} events": "Koji su objavili {number} događaja", "Who published {number} events": "Koji su objavili {number} događaja",

View file

@ -18,6 +18,13 @@
/> />
</div> </div>
<div class="start-time-icon-wrapper relative" v-if="event?.beginsOn">
<start-time-icon
:date="event.beginsOn.toString()"
class="absolute right-3 -top-16"
/>
</div>
<section class="intro px-2 pt-4" dir="auto"> <section class="intro px-2 pt-4" dir="auto">
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<div class="flex-1 min-w-[300px]"> <div class="flex-1 min-w-[300px]">
@ -290,6 +297,7 @@ import {
} from "@/types/actor"; } from "@/types/actor";
import DateCalendarIcon from "@/components/Event/DateCalendarIcon.vue"; import DateCalendarIcon from "@/components/Event/DateCalendarIcon.vue";
import SkeletonDateCalendarIcon from "@/components/Event/SkeletonDateCalendarIcon.vue"; import SkeletonDateCalendarIcon from "@/components/Event/SkeletonDateCalendarIcon.vue";
import StartTimeIcon from "@/components/Event/StartTimeIcon.vue";
import Earth from "vue-material-design-icons/Earth.vue"; import Earth from "vue-material-design-icons/Earth.vue";
import Link from "vue-material-design-icons/Link.vue"; import Link from "vue-material-design-icons/Link.vue";
import MultiCard from "@/components/Event/MultiCard.vue"; import MultiCard from "@/components/Event/MultiCard.vue";

View file

@ -27,8 +27,8 @@
<unlogged-introduction :config="config" v-if="config && !isLoggedIn" /> <unlogged-introduction :config="config" v-if="config && !isLoggedIn" />
<!-- Search fields --> <!-- Search fields -->
<search-fields v-model:search="search" v-model:location="location" /> <search-fields v-model:search="search" v-model:location="location" />
<!-- Categories preview --> <!-- Categories preview
<categories-preview /> <categories-preview /> -->
<!-- Welcome back --> <!-- Welcome back -->
<section <section
class="container mx-auto" class="container mx-auto"
@ -135,17 +135,18 @@
> >
</span> </span>
</section> </section>
<!-- Recent events --> <!-- Recent events
<CloseEvents <CloseEvents
@doGeoLoc="performGeoLocation()" @doGeoLoc="performGeoLocation()"
:userLocation="userLocation" :userLocation="userLocation"
:doingGeoloc="doingGeoloc" :doingGeoloc="doingGeoloc"
/> />
<CloseGroups :userLocation="userLocation" @doGeoLoc="performGeoLocation()" /> <CloseGroups :userLocation="userLocation" @doGeoLoc="performGeoLocation()" /> -->
<OnlineEvents /> <OnlineEvents />
<LastEvents v-if="instanceName" :instanceName="instanceName" /> <UpcomingEvents v-if="instanceName" :instanceName="instanceName" />
<!-- <LastEvents v-if="instanceName" :instanceName="instanceName" /> -->
<!-- Unlogged content section --> <!-- Unlogged content section -->
<picture v-if="!currentUser?.isLoggedIn"> <!-- <picture v-if="!currentUser?.isLoggedIn">
<source <source
media="(max-width: 799px)" media="(max-width: 799px)"
:srcset="`/img/pics/homepage-480w.webp`" :srcset="`/img/pics/homepage-480w.webp`"
@ -177,7 +178,7 @@
alt="" alt=""
loading="lazy" loading="lazy"
/> />
</picture> </picture> -->
<presentation v-if="!currentUser?.isLoggedIn" /> <presentation v-if="!currentUser?.isLoggedIn" />
</template> </template>
@ -193,9 +194,10 @@ import { HOME_USER_QUERIES } from "../graphql/home";
import RouteName from "../router/name"; import RouteName from "../router/name";
import { IEvent } from "../types/event.model"; import { IEvent } from "../types/event.model";
// import { IFollowedGroupEvent } from "../types/followedGroupEvent.model"; // import { IFollowedGroupEvent } from "../types/followedGroupEvent.model";
import CloseEvents from "@/components/Local/CloseEvents.vue"; // import CloseEvents from "@/components/Local/CloseEvents.vue";
import CloseGroups from "@/components/Local/CloseGroups.vue"; // import CloseGroups from "@/components/Local/CloseGroups.vue";
import LastEvents from "@/components/Local/LastEvents.vue"; // import LastEvents from "@/components/Local/LastEvents.vue";
import UpcomingEvents from "@/components/Local/UpcomingEvents.vue";
import OnlineEvents from "@/components/Local/OnlineEvents.vue"; import OnlineEvents from "@/components/Local/OnlineEvents.vue";
import { import {
computed, computed,

View file

@ -17,7 +17,7 @@
<li <li
v-for="log in actionLogs.elements" v-for="log in actionLogs.elements"
:key="log.id" :key="log.id"
class="bg-mbz-yellow-alt-50 hover:bg-mbz-yellow-alt-100 dark:bg-zinc-700 hover:dark:bg-zinc-600 rounded p-2 my-1" class="bg-mbz-yellow-alt-50 hover:bg-fomo-blue dark:bg-zinc-700 hover:dark:bg-zinc-600 rounded p-2 my-1"
> >
<div class="flex gap-1"> <div class="flex gap-1">
<div class="flex gap-1"> <div class="flex gap-1">

View file

@ -2,20 +2,6 @@
<section class="container mx-auto pt-4 is-max-desktop max-w-2xl"> <section class="container mx-auto pt-4 is-max-desktop max-w-2xl">
<div class=""> <div class="">
<div class=""> <div class="">
<picture>
<source
:srcset="`/img/pics/error-480w.webp 1x, /img/pics/error-1024w.webp 2x`"
type="image/webp"
/>
<img
:src="`/img/pics/error-480w.webp`"
alt=""
width="2616"
height="1698"
loading="lazy"
/>
</picture>
<h1 class="text-4xl mb-3"> <h1 class="text-4xl mb-3">
{{ $t("The page you're looking for doesn't exist.") }} {{ $t("The page you're looking for doesn't exist.") }}
</h1> </h1>

View file

@ -65,7 +65,7 @@ module.exports = {
"violet-1": "#3a384c", "violet-1": "#3a384c",
"violet-2": "#474467", "violet-2": "#474467",
"violet-3": "#3c376e", "violet-3": "#3c376e",
"yellow-1": "#ffd599", "yellow-1": "#21bef3",
"yellow-2": "#fff1de", "yellow-2": "#fff1de",
"body-background-color": "#efeef4", "body-background-color": "#efeef4",
"purple-1": "#757199", "purple-1": "#757199",
@ -75,6 +75,8 @@ module.exports = {
"mbz-danger": "#cd2026", "mbz-danger": "#cd2026",
"mbz-success": "#0d8758", "mbz-success": "#0d8758",
"mbz-warning": "#ffe08a", "mbz-warning": "#ffe08a",
"fomo-blue": "#21bef3",
"fomo-purple": "#9e9ef2",
// primary: "#272633", // primary: "#272633",
// secondary: "#ED8D07", // secondary: "#ED8D07",
}, },

View file

@ -2,7 +2,7 @@
exports[`GroupSection > renders group section with basic informations 1`] = ` exports[`GroupSection > renders group section with basic informations 1`] = `
"<section class=\\"flex flex-col mb-3 border-2 border-mbz-purple\\"> "<section class=\\"flex flex-col mb-3 border-2 border-mbz-purple\\">
<div class=\\"flex items-stretch py-3 px-1 bg-yellow-1 text-violet-title\\"> <div class=\\"flex items-stretch py-3 px-1 bg-fomo-blue text-violet-title\\">
<div class=\\"flex flex-1 gap-1\\"><span class=\\"o-icon\\"><i class=\\"mdi mdi-bullhorn 36\\"></i></span> <div class=\\"flex flex-1 gap-1\\"><span class=\\"o-icon\\"><i class=\\"mdi mdi-bullhorn 36\\"></i></span>
<h2 class=\\"text-2xl font-medium mt-0\\">My group section</h2> <h2 class=\\"text-2xl font-medium mt-0\\">My group section</h2>
</div><a href=\\"/@my_group@remotedomain.net/p\\" class=\\"self-center\\">View all</a> </div><a href=\\"/@my_group@remotedomain.net/p\\" class=\\"self-center\\">View all</a>
@ -15,8 +15,8 @@ exports[`GroupSection > renders group section with basic informations 1`] = `
`; `;
exports[`GroupSection > renders public group section 1`] = ` exports[`GroupSection > renders public group section 1`] = `
"<section class=\\"flex flex-col mb-3 border-2 border-yellow-1\\"> "<section class=\\"flex flex-col mb-3 border-2 border-fomo-blue\\">
<div class=\\"flex items-stretch py-3 px-1 bg-yellow-1 text-violet-title\\"> <div class=\\"flex items-stretch py-3 px-1 bg-fomo-blue text-violet-title\\">
<div class=\\"flex flex-1 gap-1\\"><span class=\\"o-icon\\"><i class=\\"mdi mdi-bullhorn 36\\"></i></span> <div class=\\"flex flex-1 gap-1\\"><span class=\\"o-icon\\"><i class=\\"mdi mdi-bullhorn 36\\"></i></span>
<h2 class=\\"text-2xl font-medium mt-0\\">My group section</h2> <h2 class=\\"text-2xl font-medium mt-0\\">My group section</h2>
</div><a href=\\"/@my_group@remotedomain.net/p\\" class=\\"self-center\\">View all</a> </div><a href=\\"/@my_group@remotedomain.net/p\\" class=\\"self-center\\">View all</a>

View file

@ -30,6 +30,9 @@ export default defineConfig(({ command }) => {
}), }),
visualizer(), visualizer(),
], ],
server: {
host: (isDev ? "0.0.0.0" : "localhost")
},
build: { build: {
manifest: true, manifest: true,
outDir: path.resolve(__dirname, "../priv/static"), outDir: path.resolve(__dirname, "../priv/static"),

View file

@ -22,7 +22,9 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
| {:error, | {:error,
:invalid_url | :http_gone | :http_error | :http_not_found | :content_not_json} :invalid_url | :http_gone | :http_error | :http_not_found | :content_not_json}
def fetch(url, options \\ []) do def fetch(url, options \\ []) do
on_behalf_of = Keyword.get(options, :on_behalf_of, Relay.get_actor()) Logger.debug("Fetching #{url} with AP Fetcher")
on_behalf_of = Keyword.get(options, :on_behalf_of, actor_relay())
Logger.debug("Fetching on behalf of #{inspect(on_behalf_of.url)}")
date = Signature.generate_date_header() date = Signature.generate_date_header()
headers = headers =
@ -32,29 +34,8 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
client = ActivityPubClient.client(headers: headers) client = ActivityPubClient.client(headers: headers)
if address_valid?(url) do if address_valid?(url) and url != on_behalf_of.url do
case ActivityPubClient.get(client, url) do do_fetch(url, client)
{:ok, %Tesla.Env{body: data, status: code}} when code in 200..299 and is_map(data) ->
{:ok, data}
{:ok, %Tesla.Env{status: 410}} ->
Logger.debug("Resource at #{url} is 410 Gone")
{:error, :http_gone}
{:ok, %Tesla.Env{status: 404}} ->
Logger.debug("Resource at #{url} is 404 Gone")
{:error, :http_not_found}
{:ok, %Tesla.Env{body: data}} when is_binary(data) ->
{:error, :content_not_json}
{:ok, %Tesla.Env{} = res} ->
Logger.debug("Resource returned bad HTTP code #{inspect(res)}")
{:error, :http_error}
{:error, err} ->
{:error, err}
end
else else
{:error, :invalid_url} {:error, :invalid_url}
end end
@ -169,4 +150,38 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
%URI{host: host, scheme: scheme} = URI.parse(address) %URI{host: host, scheme: scheme} = URI.parse(address)
is_valid_string(host) and is_valid_string(scheme) is_valid_string(host) and is_valid_string(scheme)
end end
defp actor_relay do
Relay.get_actor()
end
@spec do_fetch(String.t(), Tesla.Client.t()) ::
{:ok, map()}
| {:error,
:invalid_url | :http_gone | :http_error | :http_not_found | :content_not_json}
defp do_fetch(url, client) do
case ActivityPubClient.get(client, url) do
{:ok, %Tesla.Env{body: data, status: code}} when code in 200..299 and is_map(data) ->
Logger.debug("Found the following from ActivityPubClient fetch: #{inspect(data)}")
{:ok, data}
{:ok, %Tesla.Env{status: 410}} ->
Logger.debug("Resource at #{url} is 410 Gone")
{:error, :http_gone}
{:ok, %Tesla.Env{status: 404}} ->
Logger.debug("Resource at #{url} is 404 Gone")
{:error, :http_not_found}
{:ok, %Tesla.Env{body: data}} when is_binary(data) ->
{:error, :content_not_json}
{:ok, %Tesla.Env{} = res} ->
Logger.debug("Resource returned bad HTTP code #{inspect(res)}")
{:error, :http_error}
{:error, err} ->
{:error, err}
end
end
end end

View file

@ -55,7 +55,7 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
@type fetch_actor_errors :: ActivityPubActor.make_actor_errors() | fetch_collection_errors() @type fetch_actor_errors :: ActivityPubActor.make_actor_errors() | fetch_collection_errors()
@spec fetch_group(String.t(), Actor.t()) :: :ok | {:error, fetch_actor_errors} @spec fetch_group(String.t(), Actor.t()) :: :ok | {:error, fetch_actor_errors}
def fetch_group(group_url, %Actor{} = on_behalf_of) do def fetch_group(group_url, %Actor{} = on_behalf_of) when is_binary(group_url) do
Logger.debug("Fetching group #{group_url}") Logger.debug("Fetching group #{group_url}")
case ActivityPubActor.make_actor_from_url(group_url, on_behalf_of: on_behalf_of) do case ActivityPubActor.make_actor_from_url(group_url, on_behalf_of: on_behalf_of) do

View file

@ -23,7 +23,13 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do
def init do def init do
# Wait for everything to settle. # Wait for everything to settle.
Process.sleep(1000 * 5) Process.sleep(1000 * 5)
get_actor() relay = get_actor()
unless Regex.match?(~r/BEGIN RSA PRIVATE KEY/, relay.keys) do
{:ok, relay} = Actors.actor_key_rotation(relay)
end
relay
end end
@spec get_actor() :: Actor.t() | no_return @spec get_actor() :: Actor.t() | no_return

View file

@ -12,6 +12,7 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
alias Mobilizon.Federation.ActivityPub.Relay
require Logger require Logger
@ -94,7 +95,12 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
%{"keyId" => kid} = HTTPSignatures.signature_for_conn(conn) %{"keyId" => kid} = HTTPSignatures.signature_for_conn(conn)
actor_url = key_id_to_actor_url(kid) actor_url = key_id_to_actor_url(kid)
Logger.debug("Refetching public key for #{actor_url}") Logger.debug("Refetching public key for #{actor_url}")
relay = Relay.get_actor()
if actor_url == relay.url do
# Special case if ever it's our own actor fetching ourselves
get_actor_public_key(relay)
else
# In this specific case we don't sign object fetches because # In this specific case we don't sign object fetches because
# this would cause infinite recursion when servers both need # this would cause infinite recursion when servers both need
# to fetch each other's keys # to fetch each other's keys
@ -103,6 +109,7 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
get_actor_public_key(actor) get_actor_public_key(actor)
end end
end end
end
@spec sign(Actor.t(), map()) :: String.t() | {:error, :pem_decode_error} | no_return @spec sign(Actor.t(), map()) :: String.t() | {:error, :pem_decode_error} | no_return
def sign(%Actor{domain: domain, keys: keys, url: url} = actor, headers) when is_nil(domain) do def sign(%Actor{domain: domain, keys: keys, url: url} = actor, headers) when is_nil(domain) do

View file

@ -426,7 +426,7 @@ defmodule Mobilizon.Applications do
@spec prune_old_application_device_activations(pos_integer()) :: {non_neg_integer(), nil} @spec prune_old_application_device_activations(pos_integer()) :: {non_neg_integer(), nil}
def prune_old_application_device_activations(lifetime) do def prune_old_application_device_activations(lifetime) do
exp = DateTime.add(DateTime.utc_now(), -lifetime) exp = DateTime.utc_now() |> DateTime.add(-lifetime) |> DateTime.to_unix()
ApplicationDeviceActivation ApplicationDeviceActivation
|> where([at], at.expires_in < ^exp) |> where([at], at.expires_in < ^exp)

View file

@ -19,6 +19,7 @@ defmodule Mobilizon.Config do
registration_email_denylist: list(String.t()), registration_email_denylist: list(String.t()),
demo: boolean(), demo: boolean(),
repository: String.t(), repository: String.t(),
version: String.t(),
email_from: String.t(), email_from: String.t(),
email_reply_to: String.t(), email_reply_to: String.t(),
federating: boolean(), federating: boolean(),
@ -102,9 +103,7 @@ defmodule Mobilizon.Config do
end end
@spec instance_version :: String.t() @spec instance_version :: String.t()
def instance_version do def instance_version, do: instance_config()[:version]
GitStatus.commit()
end
@spec instance_hostname :: String.t() @spec instance_hostname :: String.t()
def instance_hostname, do: instance_config()[:hostname] def instance_hostname, do: instance_config()[:hostname]

View file

@ -28,126 +28,82 @@ defmodule Mobilizon.Events.Categories do
defp build_in_categories do defp build_in_categories do
[ [
%{ %{
id: :arts, id: :ausflug,
label: gettext("Arts") label: gettext("Ausflug")
}, },
%{ %{
id: :book_clubs, id: :ausstellung,
label: gettext("Book clubs") label: gettext("Ausstellung")
}, },
%{ %{
id: :business, id: :demonstration,
label: gettext("Business") label: gettext("Demonstration")
}, },
%{ %{
id: :causes, id: :einweihung,
label: gettext("Causes") label: gettext("Einweihung")
}, },
%{ %{
id: :comedy, id: :filmvorfuehrung,
label: gettext("Comedy") label: gettext("Filmvorführung")
}, },
%{ %{
id: :crafts, id: :fussball,
label: gettext("Crafts") label: gettext("Fußball")
}, },
%{ %{
id: :food_drink, id: :gedenken,
label: gettext("Food & Drink") label: gettext("Gedenken")
}, },
%{ %{
id: :health, id: :infostand,
label: gettext("Health") label: gettext("Infostand")
}, },
%{ %{
id: :music, id: :kuenstlerisches,
label: gettext("Music") label: gettext("Künstlerisches")
}, },
%{ %{
id: :auto_boat_air, id: :kneipe,
label: gettext("Auto, boat and air") label: gettext("Kneipe")
}, },
%{ %{
id: :community, id: :konzert,
label: gettext("Community") label: gettext("Konzert")
}, },
%{ %{
id: :family_education, id: :kuefa,
label: gettext("Family & Education") label: gettext("Fa")
}, },
%{ %{
id: :fashion_beauty, id: :lesung,
label: gettext("Fashion & Beauty") label: gettext("Lesung")
},
%{
id: :film_media,
label: gettext("Film & Media")
},
%{
id: :games,
label: gettext("Games")
},
%{
id: :language_culture,
label: gettext("Language & Culture")
},
%{
id: :learning,
label: gettext("Learning")
},
%{
id: :lgbtq,
label: gettext("LGBTQ")
},
%{
id: :movements_politics,
label: gettext("Movements and politics")
},
%{
id: :networking,
label: gettext("Networking")
}, },
%{ %{
id: :party, id: :party,
label: gettext("Party") label: gettext("Party")
}, },
%{ %{
id: :performing_visual_arts, id: :sport,
label: gettext("Performing & Visual Arts") label: gettext("Sport")
}, },
%{ %{
id: :pets, id: :theater,
label: gettext("Pets") label: gettext("Theater")
}, },
%{ %{
id: :photography, id: :verhandlung,
label: gettext("Photography") label: gettext("Verhandlung")
}, },
%{ %{
id: :outdoors_adventure, id: :workshop,
label: gettext("Outdoors & Adventure") label: gettext("Workshop")
},
%{
id: :spirituality_religion_beliefs,
label: gettext("Spirituality, Religion & Beliefs")
},
%{
id: :science_tech,
label: gettext("Science & Tech")
},
%{
id: :sports,
label: gettext("Sports")
},
%{
id: :theatre,
label: gettext("Theatre")
}, },
# Legacy default value # Legacy default value
%{ %{
id: :meeting, id: :meeting,
label: gettext("Meeting") label: gettext("Infoveranstaltung")
} },
] ]
end end

View file

@ -1860,7 +1860,7 @@ defmodule Mobilizon.Events do
@spec filter_future_events(Ecto.Queryable.t(), boolean) :: Ecto.Query.t() @spec filter_future_events(Ecto.Queryable.t(), boolean) :: Ecto.Query.t()
defp filter_future_events(query, true) do defp filter_future_events(query, true) do
from(q in query, from(q in query,
where: q.begins_on > ^DateTime.utc_now() where: coalesce(q.ends_on, q.begins_on) > ^DateTime.utc_now()
) )
end end

View file

@ -7,4 +7,4 @@
<%= if @follower.type == :Application do %><%= gettext "Note: %{name} following you doesn't necessarily imply that you follow this instance, but you can ask to follow them too.", name: Mobilizon.Actors.Actor.display_name_and_username(@follower) %><% end %> <%= if @follower.type == :Application do %><%= gettext "Note: %{name} following you doesn't necessarily imply that you follow this instance, but you can ask to follow them too.", name: Mobilizon.Actors.Actor.display_name_and_username(@follower) %><% end %>
<%= if @follower.type == :Application do %><%= gettext "To accept this invitation, head over to the instance's admin settings." %><% else %><%= gettext "To accept this invitation, head over to the profile's admin page." %><% end %> <%= if @follower.type == :Application do %><%= gettext "To accept this invitation, head over to the instance's admin settings." %><% else %><%= gettext "To accept this invitation, head over to the profile's admin page." %><% end %>
<%= if @follower.type == :Application do %><%= "#{Mobilizon.Web.Endpoint.url()}/settings/admin/relays/followers" %><% else %><%= "#{Mobilizon.Web.Endpoint.url()}/settings/admin/profiles/#{@follower.id}" %><% end %> <%= if @follower.type == :Application do %><%= "#{Mobilizon.Web.Endpoint.url()}/settings/admin/instances/%{name}" %><% else %><%= "#{Mobilizon.Web.Endpoint.url()}/settings/admin/profiles/#{@follower.id}" %><% end %>

View file

@ -2311,42 +2311,7 @@ msgstr "LGBTQ"
msgid "Language & Culture" msgid "Language & Culture"
msgstr "Sprache & Kultur" msgstr "Sprache & Kultur"
#: lib/mobilizon/events/categories.ex:96 #: lib/mobilizon/events/categories.ex:100
#, elixir-autogen, elixir-format
msgid "Learning"
msgstr "Lernen"
#: lib/mobilizon/events/categories.ex:149
#, elixir-autogen, elixir-format
msgid "Meeting"
msgstr "Treffen"
#: lib/mobilizon/events/categories.ex:104
#, elixir-autogen, elixir-format
msgid "Movements and politics"
msgstr "Bewegungen und Politik"
#: lib/mobilizon/events/categories.ex:64
#, elixir-autogen, elixir-format
msgid "Music"
msgstr "Musik"
#: lib/mobilizon/events/categories.ex:108
#, elixir-autogen, elixir-format
msgid "Networking"
msgstr "Netzwerke"
#: lib/mobilizon/events/categories.ex:128
#, elixir-autogen, elixir-format
msgid "Outdoors & Adventure"
msgstr "Natur & Abenteuer"
#: lib/mobilizon/events/categories.ex:112
#, elixir-autogen, elixir-format
msgid "Party"
msgstr "Party"
#: lib/mobilizon/events/categories.ex:116
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Performing & Visual Arts" msgid "Performing & Visual Arts"
msgstr "Darstellende & bildende Kunst" msgstr "Darstellende & bildende Kunst"
@ -2371,16 +2336,63 @@ msgstr "Wissenschaft & Technologie"
msgid "Spirituality, Religion & Beliefs" msgid "Spirituality, Religion & Beliefs"
msgstr "Glauben, Religion & Spiritualität" msgstr "Glauben, Religion & Spiritualität"
#: lib/mobilizon/events/categories.ex:140 msgid "Ausflug"
#, elixir-autogen, elixir-format msgstr "Ausflug"
msgid "Sports"
msgid "Ausstellung"
msgstr "Ausstellung"
msgid "Demonstration"
msgstr "Demonstration"
msgid "Einweihung"
msgstr "Einweihung"
msgid "Filmvorführung"
msgstr "Filmvorführung"
msgid "Fußball"
msgstr "Fußball"
msgid "Gedenken"
msgstr "Gedenken"
msgid "Infostand"
msgstr "Infostand"
msgid "Infoveranstaltung"
msgstr "Infoveranstaltung"
msgid "Künstlerisches"
msgstr "Künstlerisches"
msgid "Kneipe"
msgstr "Kneipe"
msgid "Konzert"
msgstr "Konzert"
msgid "KüFa"
msgstr "KüFa"
msgid "Lesung"
msgstr "Lesung"
msgid "Party"
msgstr "Party"
msgid "Sport"
msgstr "Sport" msgstr "Sport"
#: lib/mobilizon/events/categories.ex:144 msgid "Theater"
#, elixir-autogen, elixir-format
msgid "Theatre"
msgstr "Theater" msgstr "Theater"
msgid "Verhandlung"
msgstr "Verhandlung"
msgid "Workshop"
msgstr "Workshop"
#: lib/web/templates/email/participation/event_card.text.eex:9 #: lib/web/templates/email/participation/event_card.text.eex:9
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Read more: %{url}" msgid "Read more: %{url}"

View file

@ -1964,11 +1964,6 @@ msgstr ""
#: lib/mobilizon/events/categories.ex:112 #: lib/mobilizon/events/categories.ex:112
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Party"
msgstr ""
#: lib/mobilizon/events/categories.ex:116
#, elixir-autogen, elixir-format
msgid "Performing & Visual Arts" msgid "Performing & Visual Arts"
msgstr "" msgstr ""
@ -1992,15 +1987,62 @@ msgstr ""
msgid "Spirituality, Religion & Beliefs" msgid "Spirituality, Religion & Beliefs"
msgstr "" msgstr ""
#: lib/mobilizon/events/categories.ex:140 msgid "Ausflug"
#, elixir-autogen, elixir-format msgstr "Excursion"
msgid "Sports"
msgstr ""
#: lib/mobilizon/events/categories.ex:144 msgid "Ausstellung"
#, elixir-autogen, elixir-format msgstr "Exhibition"
msgid "Theatre"
msgstr "" msgid "Demonstration"
msgstr "Demonstration"
msgid "Einweihung"
msgstr "Inauguration"
msgid "Filmvorführung"
msgstr "Film screening"
msgid "Fußball"
msgstr "Football"
msgid "Gedenken"
msgstr "Remembrance"
msgid "Infostand"
msgstr "Infostand"
msgid "Infoveranstaltung"
msgstr "Info event"
msgid "Künstlerisches"
msgstr "Art related"
msgid "Kneipe"
msgstr "Bar"
msgid "Konzert"
msgstr "Concert"
msgid "KüFa"
msgstr "Kitchen for all"
msgid "Lesung"
msgstr "Reading"
msgid "Party"
msgstr "Party"
msgid "Sport"
msgstr "Sport"
msgid "Theater"
msgstr "Theater"
msgid "Verhandlung"
msgstr "Trial"
msgid "Workshop"
msgstr "Workshop"
#: lib/web/templates/email/participation/event_card.text.eex:9 #: lib/web/templates/email/participation/event_card.text.eex:9
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy