Merge branch '2.0.1' into 'main'

2.0.1

Closes #959

See merge request framasoft/mobilizon!1128
This commit is contained in:
Thomas Citharel 2021-11-26 14:15:25 +00:00
commit 79252c4a5d
35 changed files with 189 additions and 142 deletions

View File

@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 2.0.1 - 2021-11-26
### Changed
- Remove litepub context
### Fixed
- Make sure my group upcoming events are ordered by their start date
- Fix event participants pagination
- Always focus the search field after results have been fetched
- Added missing timezone data to the Docker image
- Replace @tiptap/starter-kit with indidual extensions, removing unneeded extensions that caused issues on old Firefox versions
- Better handling of Friendica Update activities without actor information
- Always show pending/cancelled status on event cards
### Translations
- Czech
- Gaelic
- Hungarian
- Indonesian
- Welsh (New !)
## 2.0.0 - 2021-11-23
Please read the [UPGRADE.md](https://framagit.org/framasoft/mobilizon/-/blob/main/UPGRADE.md#upgrading-from-13-to-20) file as well.

View File

@ -18,15 +18,20 @@ config :mobilizon, :cldr,
locales: [
"ar",
"be",
"bn",
"ca",
"cs",
"cy",
"de",
"en",
"es",
"fa",
"fi",
"fr",
"gd",
"gl",
"hu",
"id",
"it",
"ja",
"nl",
@ -35,5 +40,6 @@ config :mobilizon, :cldr,
"pl",
"pt",
"ru",
"sv"
"sv",
"zh_Hant"
]

View File

@ -1,6 +1,6 @@
{
"name": "mobilizon",
"version": "2.0.0",
"version": "2.0.1",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",

View File

@ -18,6 +18,20 @@
</div>
<div class="title-info-wrapper has-text-grey-dark">
<h3 class="event-minimalist-title" :lang="event.language" dir="auto">
<b-tag
type="is-info"
class="mr-1"
v-if="event.status === EventStatus.TENTATIVE"
>
{{ $t("Tentative") }}
</b-tag>
<b-tag
type="is-danger"
class="mr-1"
v-if="event.status === EventStatus.CANCELLED"
>
{{ $t("Cancelled") }}
</b-tag>
<b-tag
class="mr-2"
type="is-warning"
@ -105,7 +119,7 @@
import { Component, Prop, Vue } from "vue-property-decorator";
import { IEvent, organizer, organizerDisplayName } from "@/types/event.model";
import DateCalendarIcon from "@/components/Event/DateCalendarIcon.vue";
import { ParticipantRole } from "@/types/enums";
import { EventStatus, ParticipantRole } from "@/types/enums";
import RouteName from "../../router/name";
import LazyImageWrapper from "@/components/Image/LazyImageWrapper.vue";
import InlineAddress from "@/components/Address/InlineAddress.vue";
@ -129,6 +143,8 @@ export default class EventMinimalistCard extends Vue {
organizerDisplayName = organizerDisplayName;
organizer = organizer;
EventStatus = EventStatus;
}
</script>
<style lang="scss" scoped>

View File

@ -45,6 +45,22 @@
</div>
<div class="list-card-content">
<div class="title-wrapper" dir="auto">
<b-tag
type="is-info"
class="mr-1 mb-1"
size="is-medium"
v-if="participation.event.status === EventStatus.TENTATIVE"
>
{{ $t("Tentative") }}
</b-tag>
<b-tag
type="is-danger"
class="mr-1 mb-1"
size="is-medium"
v-if="participation.event.status === EventStatus.CANCELLED"
>
{{ $t("Cancelled") }}
</b-tag>
<router-link
:to="{
name: RouteName.EVENT,
@ -257,7 +273,7 @@ import { Component, Prop } from "vue-property-decorator";
import DateCalendarIcon from "@/components/Event/DateCalendarIcon.vue";
import { mixins } from "vue-class-component";
import { RawLocation, Route } from "vue-router";
import { EventVisibility, ParticipantRole } from "@/types/enums";
import { EventStatus, EventVisibility, ParticipantRole } from "@/types/enums";
import { IParticipant } from "../../types/participant.model";
import {
IEventCardOptions,
@ -326,6 +342,8 @@ export default class EventParticipationCard extends mixins(
RouteName = RouteName;
EventStatus = EventStatus;
get mergedOptions(): IEventCardOptions {
return { ...defaultOptions, ...this.options };
}

View File

@ -41,6 +41,7 @@ export const FETCH_PERSON = gql`
uuid
title
beginsOn
status
}
}
}
@ -84,6 +85,7 @@ export const GET_PERSON = gql`
uuid
title
beginsOn
status
}
}
participations(page: $participationPage, limit: $participationLimit) {
@ -95,6 +97,7 @@ export const GET_PERSON = gql`
uuid
title
beginsOn
status
}
}
}
@ -213,6 +216,7 @@ export const LOGGED_USER_DRAFTS = gql`
alt
}
beginsOn
status
visibility
attributedTo {
...ActorFragment

View File

@ -61,6 +61,7 @@ const FULL_EVENT_FRAGMENT = gql`
uuid
title
beginsOn
status
language
picture {
id
@ -438,6 +439,7 @@ export const FETCH_GROUP_EVENTS = gql`
uuid
title
beginsOn
status
draft
options {
...EventOptions

View File

@ -42,6 +42,7 @@ export const LIST_GROUPS = gql`
id
uuid
title
status
beginsOn
}
total
@ -104,6 +105,7 @@ export const GROUP_FIELDS_FRAGMENTS = gql`
uuid
title
beginsOn
status
draft
language
options {

View File

@ -36,6 +36,7 @@ export const HOME_USER_QUERIES = gql`
alt
}
beginsOn
status
visibility
language
organizerActor {
@ -77,6 +78,7 @@ export const HOME_USER_QUERIES = gql`
uuid
title
beginsOn
status
picture {
url
}
@ -127,6 +129,7 @@ export const CLOSE_CONTENT = gql`
title
uuid
beginsOn
status
picture {
id
url

View File

@ -32,6 +32,7 @@ export const LOGGED_USER_PARTICIPATIONS = gql`
alt
}
beginsOn
status
visibility
organizerActor {
...ActorFragment
@ -98,6 +99,7 @@ export const LOGGED_USER_UPCOMING_EVENTS = gql`
alt
}
beginsOn
status
visibility
organizerActor {
...ActorFragment
@ -144,6 +146,7 @@ export const LOGGED_USER_UPCOMING_EVENTS = gql`
uuid
title
beginsOn
status
picture {
url
}

View File

@ -38,6 +38,7 @@ export const SEARCH_EVENTS_AND_GROUPS = gql`
id
url
}
status
tags {
...TagFragment
}
@ -108,6 +109,7 @@ export const INTERACT = gql`
title
uuid
beginsOn
status
picture {
id
url

View File

@ -1,26 +1,24 @@
{
"ar": "العربية",
"be": "Беларуская мова",
"bn": "বাংলা",
"ca": "Català",
"cs": "čeština",
"cy": "Cymraeg",
"de": "Deutsch",
"en": "English",
"eo": "Esperanto",
"es": "Español",
"eu": "Euskara",
"fa": "فارسی",
"fi": "suomi",
"fr": "Français",
"gd": "Gàidhlig",
"gl": "Galego",
"hu": "Magyar",
"id": "Bahasa Indonesia",
"it": "Italiano",
"ja": "日本語",
"kn": "Kannada",
"nl": "Dutch",
"nl": "Nederlands",
"nn": "Nynorsk",
"oc": "Occitan",
"pl": "Polski",
"pt": "Português",
"pt_BR": "Português brasileiro",
"ru": "Русский",
"sl": "Slovenščina",

View File

@ -1422,9 +1422,9 @@
string.prototype.matchall "^4.0.6"
"@tiptap/core@^2.0.0-beta.41":
version "2.0.0-beta.142"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.142.tgz#44e5dc9f63719669fefad422ddae671e8cfe37c4"
integrity sha512-0oAkc2a4ZKI+1yfqAM9EN5Rk9KwJyosLEQutKK43c8ufdUawfIeEJEIG99rsm2AfORSk4e2eyMwkUwUoBht7gw==
version "2.0.0-beta.143"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.143.tgz#e1eb470351867eb13a8f2169958f2231138a6dc1"
integrity sha512-3AoKMZmuc+Lh/ZsM7dj+mSQvRMFANgLVAT0Fza9DaEMREnbpS6nDZlpcbb0HnoExbd7ZLobuwDGxEIZG5uo3Lw==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-keymap" "^1.0.4"
@ -4051,7 +4051,7 @@ deepmerge@^4.2.2:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
default-gateway@^6.0.0, default-gateway@^6.0.3:
default-gateway@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71"
integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==
@ -4275,9 +4275,9 @@ ejs@^3.1.6:
jake "^10.6.1"
electron-to-chromium@^1.3.896:
version "1.4.1"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.1.tgz#623f8fa6ee416e016d93f00efc34fbc73f9f59ed"
integrity sha512-9ldvb6QMHiDpUNF1iSwBTiTT0qXEN+xIO5WlCJrC5gt0z74ofOiqR698vaJqYWnri0XZiF0YmnrFmGq/EmpGAA==
version "1.4.3"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.3.tgz#82480df3ef607f04bb38cc3f30a628d8b895339f"
integrity sha512-hfpppjYhqIZB8jrNb0rNceQRkSnBN7QJl3W26O1jUv3F3BkQknqy1YTqVXkFnIcFtBc3Qnv5M7r5Lez2iOLgZA==
emittery@^0.8.1:
version "0.8.1"
@ -5525,16 +5525,6 @@ ini@^1.3.4:
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
internal-ip@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1"
integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==
dependencies:
default-gateway "^6.0.0"
ipaddr.js "^1.9.1"
is-ip "^3.1.0"
p-event "^4.2.0"
internal-slot@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
@ -5554,17 +5544,12 @@ intersection-observer@^0.12.0:
resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.12.0.tgz#6c84628f67ce8698e5f9ccf857d97718745837aa"
integrity sha512-2Vkz8z46Dv401zTWudDGwO7KiGHNDkMv417T5ItcNYfmvHR/1qCTVBO9vwH8zZmQ0WkA/1ARwpysR9bsnop4NQ==
ip-regex@^4.0.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5"
integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==
ip@^1.1.0:
version "1.1.5"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
ipaddr.js@1.9.1, ipaddr.js@^1.9.1:
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
@ -5694,13 +5679,6 @@ is-interactive@^1.0.0:
resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
is-ip@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8"
integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==
dependencies:
ip-regex "^4.0.0"
is-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
@ -7264,13 +7242,6 @@ p-debounce@^4.0.0:
resolved "https://registry.yarnpkg.com/p-debounce/-/p-debounce-4.0.0.tgz#348e3f44489baa9435cc7d807f17b3bb2fb16b24"
integrity sha512-4Ispi9I9qYGO4lueiLDhe4q4iK5ERK8reLsuzH6BPaXn53EGaua8H66PXIFGrW897hwjXp+pVLrm/DLxN0RF0A==
p-event@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5"
integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==
dependencies:
p-timeout "^3.1.0"
p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
@ -7319,13 +7290,6 @@ p-retry@^4.5.0:
"@types/retry" "^0.12.0"
retry "^0.13.1"
p-timeout@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe"
integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==
dependencies:
p-finally "^1.0.0"
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@ -9618,7 +9582,7 @@ walker@^1.0.7:
dependencies:
makeerror "1.0.12"
watchpack@^2.2.0:
watchpack@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.0.tgz#a41bca3da6afaff31e92a433f4c856a0c25ea0c4"
integrity sha512-MnN0Q1OsvB/GGHETrFeZPQaOelWh/7O+EiFlj8sM9GPjtQkis7k01aAxrg/18kTfoIVcLL+haEVFlXDaSRwKRw==
@ -9713,9 +9677,9 @@ webpack-dev-middleware@^5.2.1:
schema-utils "^4.0.0"
webpack-dev-server@^4.1.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.5.0.tgz#614b5112cfa4730a4801bb4ddebb3be5b0d70497"
integrity sha512-Ss4WptsUjYa+3hPI4iYZYEc8FrtnfkaPrm5WTjk9ux5kiCS718836srs0ppKMHRaCHP5mQ6g4JZGcfDdGbCjpQ==
version "4.6.0"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.6.0.tgz#e8648601c440172d9b6f248d28db98bed335315a"
integrity sha512-oojcBIKvx3Ya7qs1/AVWHDgmP1Xml8rGsEBnSobxU/UJSX1xP1GPM3MwsAnDzvqcVmVki8tV7lbcsjEjk0PtYg==
dependencies:
ansi-html-community "^0.0.8"
bonjour "^3.5.0"
@ -9723,17 +9687,17 @@ webpack-dev-server@^4.1.0:
colorette "^2.0.10"
compression "^1.7.4"
connect-history-api-fallback "^1.6.0"
default-gateway "^6.0.3"
del "^6.0.0"
express "^4.17.1"
graceful-fs "^4.2.6"
html-entities "^2.3.2"
http-proxy-middleware "^2.0.0"
internal-ip "^6.2.0"
ipaddr.js "^2.0.1"
open "^8.0.9"
p-retry "^4.5.0"
portfinder "^1.0.28"
schema-utils "^3.1.0"
schema-utils "^4.0.0"
selfsigned "^1.10.11"
serve-index "^1.9.1"
sockjs "^0.3.21"
@ -9770,9 +9734,9 @@ webpack-virtual-modules@^0.4.2:
integrity sha512-5NUqC2JquIL2pBAAo/VfBP6KuGkHIZQXW/lNKupLPfhViwh8wNsu0BObtl09yuKZszeEUfbXz8xhrHvSG16Nqw==
webpack@*, webpack@^5.38.1, webpack@^5.54.0:
version "5.64.3"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.64.3.tgz#f4792cc3f8528db2c18375fa2cd269f69e0bf69f"
integrity sha512-XF6/IL9Bw2PPQioiR1UYA8Bs4tX3QXJtSelezKECdLFeSFzWoe44zqTzPW5N+xI3fACaRl2/G3sNA4WYHD7Iww==
version "5.64.4"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.64.4.tgz#e1454b6a13009f57cc2c78e08416cd674622937b"
integrity sha512-LWhqfKjCLoYJLKJY8wk2C3h77i8VyHowG3qYNZiIqD6D0ZS40439S/KVuc/PY48jp2yQmy0mhMknq8cys4jFMw==
dependencies:
"@types/eslint-scope" "^3.7.0"
"@types/estree" "^0.0.50"
@ -9796,7 +9760,7 @@ webpack@*, webpack@^5.38.1, webpack@^5.54.0:
schema-utils "^3.1.0"
tapable "^2.1.1"
terser-webpack-plugin "^5.1.3"
watchpack "^2.2.0"
watchpack "^2.3.0"
webpack-sources "^3.2.2"
websocket-driver@>=0.5.1, websocket-driver@^0.7.4:

View File

@ -155,7 +155,7 @@ defmodule Mobilizon.Federation.ActivityPub do
end
# Create an activity from an event
@spec event_to_activity(%Event{}, boolean()) :: Activity.t()
@spec event_to_activity(Event.t(), boolean()) :: Activity.t()
defp event_to_activity(%Event{} = event, local \\ true) do
%Activity{
recipients: [@public_ap_adress],
@ -166,7 +166,7 @@ defmodule Mobilizon.Federation.ActivityPub do
end
# Create an activity from a comment
@spec comment_to_activity(%Comment{}, boolean()) :: Activity.t()
@spec comment_to_activity(Comment.t(), boolean()) :: Activity.t()
defp comment_to_activity(%Comment{} = comment, local \\ true) do
%Activity{
recipients: [@public_ap_adress],

View File

@ -77,7 +77,7 @@ defmodule Mobilizon.Federation.ActivityPub.Permission do
@spec can_manage_group_object?(
existing_object_permissions(),
%Actor{url: String.t()},
Actor.t(),
object()
) :: boolean()
defp can_manage_group_object?(permission, %Actor{url: actor_url} = actor, object) do

View File

@ -967,10 +967,8 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
defp do_handle_incoming_reject_invite(invite_object, %Actor{} = actor_rejecting) do
with {:invite, {:ok, %Member{role: :invited, actor_id: actor_id} = member}} <-
{:invite, get_member(invite_object)},
{:same_actor, true} <- {:same_actor, actor_rejecting.id == actor_id},
{:ok, activity, member} <-
Actions.Reject.reject(:invite, member, false) do
{:ok, activity, member}
{:same_actor, true} <- {:same_actor, actor_rejecting.id == actor_id} do
Actions.Reject.reject(:invite, member, false)
end
end

View File

@ -149,25 +149,23 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
),
tags <- ConverterUtils.fetch_tags(tags),
mentions <- Map.get(args, :mentions, []) ++ ConverterUtils.fetch_mentions(mentions),
lang <- Map.get(args, :language, "und"),
args <-
Map.merge(args, %{
actor_id: Map.get(args, :actor_id),
text: text,
mentions: mentions,
tags: tags,
event: event,
in_reply_to_comment: in_reply_to_comment,
in_reply_to_comment_id:
if(is_nil(in_reply_to_comment), do: nil, else: Map.get(in_reply_to_comment, :id)),
origin_comment_id:
if(is_nil(in_reply_to_comment),
do: nil,
else: Comment.get_thread_id(in_reply_to_comment)
),
language: if(lang == "und", do: LanguageDetection.detect(:comment, args), else: lang)
}) do
args
lang <- Map.get(args, :language, "und") do
Map.merge(args, %{
actor_id: Map.get(args, :actor_id),
text: text,
mentions: mentions,
tags: tags,
event: event,
in_reply_to_comment: in_reply_to_comment,
in_reply_to_comment_id:
if(is_nil(in_reply_to_comment), do: nil, else: Map.get(in_reply_to_comment, :id)),
origin_comment_id:
if(is_nil(in_reply_to_comment),
do: nil,
else: Comment.get_thread_id(in_reply_to_comment)
),
language: if(lang == "und", do: LanguageDetection.detect(:comment, args), else: lang)
})
end
end

View File

@ -189,7 +189,7 @@ defmodule Mobilizon.Federation.WebFinger do
{:ok, String.t()} | {:error, :link_not_found} | {:error, any()}
defp find_webfinger_endpoint(domain) when is_binary(domain) do
with {:ok, %Tesla.Env{status: 200, body: body}} <-
fetch_document("http://#{domain}/.well-known/host-meta"),
HostMetaClient.get("http://#{domain}/.well-known/host-meta"),
link_template when is_binary(link_template) <- find_link_from_template(body) do
{:ok, link_template}
else
@ -258,11 +258,6 @@ defmodule Mobilizon.Federation.WebFinger do
{:error, :link_not_found}
end
@spec fetch_document(String.t()) :: Tesla.Env.result()
defp fetch_document(endpoint) do
with {:error, err} <- HostMetaClient.get(endpoint), do: {:error, err}
end
@spec address_invalid(String.t()) :: false | {:error, :invalid_address}
defp address_invalid(address) do
with %URI{host: host, scheme: scheme} <- URI.parse(address),

View File

@ -39,9 +39,7 @@ defmodule Mobilizon.Federation.WebFinger.XmlBuilder do
defp to_xml(content) when is_binary(content), do: to_string(content)
defp to_xml(content) when is_list(content) do
content
|> Enum.map(&to_xml/1)
|> Enum.join()
Enum.map_join(content, &to_xml/1)
end
defp to_xml(%NaiveDateTime{} = time), do: NaiveDateTime.to_iso8601(time)
@ -49,9 +47,7 @@ defmodule Mobilizon.Federation.WebFinger.XmlBuilder do
@spec make_open_tag(tag :: atom, attributes :: map()) :: String.t()
defp make_open_tag(tag, attributes) do
attributes_string =
attributes
|> Enum.map(fn {attribute, value} -> "#{attribute}=\"#{value}\"" end)
|> Enum.join(" ")
Enum.map_join(attributes, " ", fn {attribute, value} -> "#{attribute}=\"#{value}\"" end)
[to_string(tag), attributes_string] |> Enum.join(" ") |> String.trim()
end

View File

@ -21,7 +21,7 @@ defmodule Mobilizon.GraphQL.API.Utils do
text
|> Formatter.html_escape("text/plain")
|> Formatter.linkify(options)
|> (fn {text, mentions, tags} -> {String.replace(text, ~r/\r?\n/, "<br>"), mentions, tags} end).()
|> inject_new_lines()
end
def format_input(text, "text/html", options) do
@ -30,6 +30,10 @@ defmodule Mobilizon.GraphQL.API.Utils do
|> Formatter.linkify(options)
end
defp inject_new_lines({text, mentions, tags}) do
{String.replace(text, ~r/\r?\n/, "<br>"), mentions, tags}
end
@doc """
Use the data-media-id attributes to extract media from body text
"""

View File

@ -15,7 +15,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Media do
See Mobilizon.Web.Resolvers.Event.create_event/3
"""
def media(%{picture_id: media_id} = _parent, _args, _resolution) do
with {:ok, media} <- do_fetch_media(media_id), do: {:ok, media}
do_fetch_media(media_id)
end
def media(%{picture: media} = _parent, _args, _resolution), do: {:ok, media}

View File

@ -559,11 +559,9 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
Enum.each(actors, fn actor ->
actor_performing = Keyword.get(options, :actor_performing, actor)
Actions.Delete.delete(actor, actor_performing, true)
end),
# Delete user
{:ok, user} <-
Users.delete_user(user, reserve_email: Keyword.get(options, :reserve_email, activated)) do
{:ok, user}
end) do
# Delete user
Users.delete_user(user, reserve_email: Keyword.get(options, :reserve_email, activated))
end
end

View File

@ -181,7 +181,7 @@ defmodule Mix.Tasks.Mobilizon.Instance do
else
shell_error(
"The task would have overwritten the following files:\n" <>
(will_overwrite |> Enum.map(&"- #{&1}\n") |> Enum.join("")) <>
Enum.map_join(will_overwrite, "", &"- #{&1}\n") <>
"Rerun with `-f/--force` to overwrite them."
)
end

View File

@ -47,7 +47,7 @@ defmodule Mix.Tasks.Mobilizon.Users.Show do
defp display_actors(actors) do
"""
Identities (#{length(actors)}):
#{actors |> Enum.map(&display_actor/1) |> Enum.join("")}
#{Enum.map_join(actors, &display_actor/1)}
"""
end

View File

@ -57,8 +57,7 @@ defmodule Mobilizon.Service.Address do
name: if(defined?(postal_code), do: "#{description} (#{postal_code})", else: description),
alternative_name:
[locality, country]
|> Enum.filter(& &1)
|> Enum.filter(&(&1 != description))
|> Enum.filter(&(&1 && &1 != description))
|> Enum.join(", ")
}
end

View File

@ -46,10 +46,9 @@ defmodule Mobilizon.Service.CleanOrphanMedia do
[from: "posts_medias", param: "media_id"],
[from: "comments_medias", param: "media_id"]
]
|> Enum.map(fn [from: from, param: param] ->
|> Enum.map_join(" UNION ", fn [from: from, param: param] ->
"SELECT 1 FROM #{from} WHERE #{from}.#{param} = m0.id"
end)
|> Enum.join(" UNION ")
|> (&"NOT EXISTS(#{&1})").()
@spec find_media(Keyword.t()) :: list(list(Media.t()))

View File

@ -41,7 +41,7 @@ defmodule Mobilizon.Service.Export.Participants.CSV do
|> Repo.stream()
|> Stream.map(&to_list/1)
|> NimbleCSV.RFC4180.dump_to_iodata()
|> (fn stream -> Stream.concat([Enum.join(columns(), ","), "\n"], stream) end).()
|> add_header_column()
|> Stream.each(fn line -> IO.write(file, line) end)
|> Stream.run()
@ -63,6 +63,10 @@ defmodule Mobilizon.Service.Export.Participants.CSV do
end
end
defp add_header_column(stream) do
Stream.concat([Enum.join(columns(), ","), "\n"], stream)
end
@spec save_csv_upload(String.t(), String.t(), Event.t()) ::
{:ok, Export.t()} | {:error, atom() | Ecto.Changeset.t()}
defp save_csv_upload(full_path, filename, %Event{id: event_id, title: title}) do

View File

@ -39,7 +39,7 @@ defmodule Mobilizon.Service.Export.Participants.ODS do
|> Events.participant_for_event_export_query(Keyword.get(options, :roles, []))
|> Repo.all()
|> Enum.map(&to_list/1)
|> (fn data -> Enum.concat([columns()], data) end).()
|> add_header_columns()
|> generate_ods()
File.write!(full_path, content)
@ -62,6 +62,10 @@ defmodule Mobilizon.Service.Export.Participants.ODS do
end
end
defp add_header_columns(data) do
Enum.concat([columns()], data)
end
defp generate_ods(data) do
data
|> Jason.encode!()

View File

@ -15,6 +15,8 @@ defmodule Mobilizon.Service.Formatter do
alias Mobilizon.Web.Endpoint
# https://github.com/rrrene/credo/issues/912
# credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
@link_regex ~r"((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+"ui
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/

View File

@ -56,8 +56,6 @@ defmodule Mobilizon.Service.Workers.BuildSearch do
end
defp get_tags_string(%Event{tags: tags}) do
tags
|> Enum.map(& &1.title)
|> Enum.join(" ")
Enum.map_join(tags, " ", & &1.title)
end
end

View File

@ -77,12 +77,16 @@ defmodule Mobilizon.Service.Workers.LegacyNotifierBuilder do
) do
event_uuid
|> Events.get_event_by_uuid_with_preload()
|> (fn %Event{organizer_actor: %Actor{id: actor_id}} -> [actor_id] end).()
|> organizer_actor_id()
|> users_from_actor_ids(Keyword.fetch!(options, :author_id))
end
defp users_to_notify(_, _), do: []
defp organizer_actor_id(%Event{organizer_actor: %Actor{id: actor_id}}) do
[actor_id]
end
@spec users_from_actor_ids(list(), integer() | String.t()) :: list(Users.t())
defp users_from_actor_ids(actor_ids, author_id) do
actor_ids

View File

@ -294,20 +294,22 @@ defmodule Mobilizon.Web.ReverseProxy do
headers
|> downcase_headers()
|> Enum.filter(fn {k, _} -> k in @keep_req_headers end)
|> (fn headers ->
headers = headers ++ Keyword.get(opts, :req_headers, [])
|> maybe_keep_user_agent(opts)
end
if Keyword.get(opts, :keep_user_agent, false) do
List.keystore(
headers,
"user-agent",
0,
{"user-agent", Mobilizon.user_agent()}
)
else
headers
end
end).()
defp maybe_keep_user_agent(headers, opts) do
headers = headers ++ Keyword.get(opts, :req_headers, [])
if Keyword.get(opts, :keep_user_agent, false) do
List.keystore(
headers,
"user-agent",
0,
{"user-agent", Mobilizon.user_agent()}
)
else
headers
end
end
@spec build_resp_headers(list(tuple()), Keyword.t()) :: list(tuple())
@ -316,7 +318,11 @@ defmodule Mobilizon.Web.ReverseProxy do
|> Enum.filter(fn {k, _} -> k in @keep_resp_headers end)
|> build_resp_cache_headers(opts)
|> build_resp_content_disposition_header(opts)
|> (fn headers -> headers ++ Keyword.get(opts, :resp_headers, []) end).()
|> maybe_add_headers_from_opts(opts)
end
defp maybe_add_headers_from_opts(headers, opts) do
headers ++ Keyword.get(opts, :resp_headers, [])
end
@spec build_resp_cache_headers(list(tuple()), Keyword.t()) :: list(tuple())

View File

@ -1,7 +1,7 @@
defmodule Mobilizon.Mixfile do
use Mix.Project
@version "2.0.0"
@version "2.0.1"
def project do
[

View File

@ -18,7 +18,7 @@
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
"credo": {:hex, :credo, "1.5.6", "e04cc0fdc236fefbb578e0c04bd01a471081616e741d386909e527ac146016c6", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "4b52a3e558bd64e30de62a648518a5ea2b6e3e5d2b164ef5296244753fc7eb17"},
"credo": {:hex, :credo, "1.6.1", "7dc76dcdb764a4316c1596804c48eada9fff44bd4b733a91ccbf0c0f368be61e", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "698607fb5993720c7e93d2d8e76f2175bba024de964e160e2f7151ef3ab82ac5"},
"dataloader": {:hex, :dataloader, "1.0.7", "58351b335673cf40601429bfed6c11fece6ce7ad169b2ac0f0fe83e716587391", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "12bf66478e4a5085d09dc96932d058c206ee8c219cc7691d12a40dc35c8cefaa"},
"db_connection": {:hex, :db_connection, "2.4.1", "6411f6e23f1a8b68a82fa3a36366d4881f21f47fc79a9efb8c615e62050219da", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ea36d226ec5999781a9a8ad64e5d8c4454ecedc7a4d643e4832bf08efca01f00"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
@ -43,14 +43,14 @@
"ex_cldr_dates_times": {:hex, :ex_cldr_dates_times, "2.10.0", "88ef1369839e5faaea163b663f22133a2e05ca9c7266b700d993140439507603", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:ex_cldr_calendars, "~> 1.17", [hex: :ex_cldr_calendars, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.23", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "1c2072dd2f798393c48bb61217b14af89b1833b7601dd29a73a9254125679695"},
"ex_cldr_languages": {:hex, :ex_cldr_languages, "0.3.0", "91df38c2f5e89177e22dc70110ab3b131af381ad1063d3e6835ed30fddd42ed2", [:mix], [{:ex_cldr, "~> 2.24.0", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "6b473e4d91b37c6b7d09f8ea8127c3431f855b20c546c733a1c43a4ec914197e"},
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.23.0", "f77f2bc7ba3a09c5491c8c0dec9485113beb03582578a7c6377f9519ab65fc76", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.24", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.12", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "163a5fb4ed374b8f0290ec1809db475f8f874aa456e7f9ea120fcdedc93b63f7"},
"ex_doc": {:hex, :ex_doc, "0.25.5", "ac3c5425a80b4b7c4dfecdf51fa9c23a44877124dd8ca34ee45ff608b1c6deb9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "688cfa538cdc146bc4291607764a7f1fcfa4cce8009ecd62de03b27197528350"},
"ex_doc": {:hex, :ex_doc, "0.26.0", "1922164bac0b18b02f84d6f69cab1b93bc3e870e2ad18d5dacb50a9e06b542a3", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2775d66e494a9a48355db7867478ffd997864c61c65a47d31c4949459281c78d"},
"ex_ical": {:hex, :ex_ical, "0.2.0", "4b928b554614704016cc0c9ee226eb854da9327a1cc460457621ceacb1ac29a6", [:mix], [{:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "db76473b2ae0259e6633c6c479a5a4d8603f09497f55c88f9ef4d53d2b75befb"},
"ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"},
"ex_optimizer": {:hex, :ex_optimizer, "0.1.1", "62da37e206fc2233ff7a4e54e40eae365c40f96c81992fcd15b782eb25169b80", [:mix], [{:file_info, "~> 0.0.4", [hex: :file_info, repo: "hexpm", optional: false]}], "hexpm", "e6f5c059bcd58b66be2f6f257fdc4f69b74b0fa5c9ddd669486af012e4b52286"},
"ex_unit_notifier": {:hex, :ex_unit_notifier, "1.2.0", "73ced2ecee0f2da0705e372c21ce61e4e5d927ddb797f73928e52818b9cc1754", [:mix], [], "hexpm", "f38044c9d50de68ad7f0aec4d781a10d9f1c92c62b36bf0227ec0aaa96aee332"},
"exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], [], "hexpm", "1222419f706e01bfa1095aec9acf6421367dcfab798a6f67c54cf784733cd6b5"},
"excoveralls": {:hex, :excoveralls, "0.14.4", "295498f1ae47bdc6dce59af9a585c381e1aefc63298d48172efaaa90c3d251db", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e3ab02f2df4c1c7a519728a6f0a747e71d7d6e846020aae338173619217931c1"},
"exgravatar": {:hex, :exgravatar, "2.0.2", "638412896170409da114f98947d3f8d4f38e851b0e329c1cc4cd324d5e2ea081", [:mix], [], "hexpm", "f3deb5baa6fcf354a965d794ee73a956d95f1f79f41bddf69800c713cfb014a1"},
"exgravatar": {:hex, :exgravatar, "2.0.3", "2349709832ee535f826f48db98cddd294ae62b01acb44d539a16419bd8ebc3e5", [:mix], [], "hexpm", "aca18ff9bd8991d3be3e5446d3bdefc051be084c1ffc9ab2d43b3e65339300e1"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"},
"export": {:hex, :export, "0.1.1", "6dfd268b0692428f89b9285859a2dc02b6dcd2e8fdfbca34ac6e6a331351df91", [:mix], [{:erlport, "~> 0.9", [hex: :erlport, repo: "hexpm", optional: false]}], "hexpm", "3da7444ff4053f1824352f4bdb13fbd2c28c93c2011786fb686b649fdca1021f"},
"fast_html": {:hex, :fast_html, "2.0.4", "4910ee49f2f6b19692e3bf30bf97f1b6b7dac489cd6b0f34cd0fe3042c56ba30", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "3bb49d541dfc02ad5e425904f53376d758c09f89e521afc7d2b174b3227761ea"},
@ -126,7 +126,7 @@
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"struct_access": {:hex, :struct_access, "1.1.2", "a42e6ceedd9b9ea090ee94a6da089d56e16f374dbbc010c3eebdf8be17df286f", [:mix], [], "hexpm", "e4c411dcc0226081b95709909551fc92b8feb1a3476108348ea7e3f6c12e586a"},
"sweet_xml": {:hex, :sweet_xml, "0.7.1", "a2cac8e2101237e617dfa9d427d44b8aff38ba6294f313ffb4667524d6b71b98", [:mix], [], "hexpm", "8bc7b7b584a6a87113071d0d2fd39fe2251cf2224ecaeed7093bdac1b9c1555f"},
"sweet_xml": {:hex, :sweet_xml, "0.7.2", "4729f997286811fabdd8288f8474e0840a76573051062f066c4b597e76f14f9f", [:mix], [], "hexpm", "6894e68a120f454534d99045ea3325f7740ea71260bc315f82e29731d570a6e8"},
"telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},
"tesla": {:hex, :tesla, "1.4.3", "f5a494e08fb1abe4fd9c28abb17f3d9b62b8f6fc492860baa91efb1aab61c8a0", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "e0755bb664bf4d664af72931f320c97adbf89da4586670f4864bf259b5750386"},
"timex": {:hex, :timex, "3.7.6", "502d2347ec550e77fdf419bc12d15bdccd31266bb7d925b30bf478268098282f", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a296327f79cb1ec795b896698c56e662ed7210cc9eb31f0ab365eb3a62e2c589"},

View File

@ -19,7 +19,7 @@ defmodule Mobilizon.Service.ICalendarTest do
VERSION:2.0
PRODID:-//Elixir ICalendar//Mobilizon #{Mobilizon.Config.instance_version()}//EN
BEGIN:VEVENT
CATEGORIES:#{event.tags |> Enum.map(& &1.title) |> Enum.join(",")}
CATEGORIES:#{Enum.map_join(event.tags, ",", & &1.title)}
DESCRIPTION:Ceci est une description avec une première phrase assez longue\\,\\n puis sur une seconde ligne
DTEND:#{Value.to_ics(event.ends_on)}Z
DTSTAMP:#{Value.to_ics(event.publish_at)}Z