Merge branch 'bugs' into 'master'

Various bugfixes

See merge request framasoft/mobilizon!1096
This commit is contained in:
Thomas Citharel 2021-11-04 18:11:46 +00:00
commit 0625e7f3e0
40 changed files with 212 additions and 96 deletions

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" dir="auto">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

View file

@ -246,7 +246,6 @@ export default class App extends Vue {
/* Icons */
$mdi-font-path: "~@mdi/font/fonts";
@import "~@mdi/font/scss/materialdesignicons";
@import "common";
#mobilizon {

View file

@ -1,3 +1,4 @@
@use "@/styles/_mixins" as *;
@import "variables.scss";
@import "~bulma";
@ -39,7 +40,7 @@ $color-black: #000;
border-radius: 5px;
padding: 0.2rem;
white-space: nowrap;
margin-right: 0.2rem;
@include margin-right(0.2rem);
}
.mention-suggestion {
@ -48,7 +49,7 @@ $color-black: #000;
.mention .mention {
background: initial;
margin-right: 0;
@include margin-right(0);
}
.select select {

View file

@ -53,6 +53,7 @@ export default class ActorCard extends Vue {
</style>
<style lang="scss">
@use "@/styles/_mixins" as *;
.tooltip {
display: block !important;
z-index: 10000;
@ -105,7 +106,7 @@ export default class ActorCard extends Vue {
}
&[x-placement^="right"] {
margin-left: 5px;
@include margin-left(5px);
.tooltip-arrow {
border-width: 5px 5px 5px 0;
@ -114,13 +115,13 @@ export default class ActorCard extends Vue {
border-bottom-color: transparent !important;
left: -5px;
top: calc(50% - 5px);
margin-left: 0;
margin-right: 0;
@include margin-left(0);
@include margin-right(0);
}
}
&[x-placement^="left"] {
margin-right: 5px;
@include margin-right(5px);
.tooltip-arrow {
border-width: 5px 0 5px 5px;
@ -129,8 +130,8 @@ export default class ActorCard extends Vue {
border-bottom-color: transparent !important;
right: -5px;
top: calc(50% - 5px);
margin-left: 0;
margin-right: 0;
@include margin-left(0);
@include margin-right(0);
}
}

View file

@ -26,6 +26,7 @@ export default class ActorInline extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
div.actor-inline {
align-items: flex-start;
display: inline-flex;
@ -36,7 +37,7 @@ div.actor-inline {
flex-basis: auto;
flex-grow: 0;
flex-shrink: 0;
margin-right: 0.5rem;
@include margin-right(0.5rem);
}
div.actor-name {
flex-basis: auto;

View file

@ -103,6 +103,7 @@ export default class AddressInfo extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
address {
font-style: normal;
display: flex;
@ -118,7 +119,7 @@ address {
}
span.icon {
padding-right: 1rem;
@include padding-right(1rem);
}
}
</style>

View file

@ -336,6 +336,7 @@ export default class Comment extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
form.reply {
padding-bottom: 1rem;
}
@ -355,7 +356,7 @@ form.reply {
}
& > small {
margin-left: 0.3rem;
@include margin-left(0.3rem);
}
}
@ -365,14 +366,14 @@ form.reply {
.editor {
flex: 1;
padding-right: 10px;
@include padding-right(10px);
margin-bottom: 0;
}
}
a.comment-link {
text-decoration: none;
margin-left: 5px;
@include margin-left(5px);
color: $text;
&:hover {
text-decoration: underline;
@ -416,7 +417,7 @@ a.comment-link {
}
.media-left {
margin-right: 0.5rem;
@include margin-right(5px);
}
}
@ -427,7 +428,7 @@ a.comment-link {
display: flex;
flex-direction: column;
align-items: center;
margin-right: 10px;
@include margin-right(10px);
.vertical-border {
width: 3px;
@ -516,7 +517,7 @@ article {
}
.reply-action .icon {
padding-right: 0.4rem;
@include padding-right(0.4rem);
}
.visually-hidden {

View file

@ -363,6 +363,7 @@ export default class CommentTree extends Vue {
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
form.new-comment {
padding-bottom: 1rem;
@ -373,7 +374,7 @@ form.new-comment {
.field {
flex: 1;
padding-right: 10px;
@include padding-right(10px);
margin-bottom: 0;
&.notify-participants {

View file

@ -148,6 +148,7 @@ export default class DiscussionComment extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
article.comment {
display: flex;
border-top: 1px solid #e9e9e9;
@ -163,7 +164,7 @@ article.comment {
padding: 0 1rem 0.3em;
.name {
margin-right: auto;
@include margin-right(auto);
flex: 1 1 auto;
overflow: hidden;
@ -216,7 +217,7 @@ article.comment {
::v-deep blockquote {
border-left: 0.2em solid #333;
display: block;
padding-left: 1em;
@include padding-left(1em);
}
::v-deep p {

View file

@ -83,6 +83,7 @@ export default class DiscussionListItem extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
.discussion-minimalist-card-wrapper {
text-decoration: none;
display: flex;
@ -92,7 +93,7 @@ export default class DiscussionListItem extends Vue {
align-items: center;
.calendar-icon {
margin-right: 1rem;
@include margin-right(1rem);
}
.title-info-wrapper {

View file

@ -376,6 +376,7 @@ export default class EditorComponent extends Vue {
}
</script>
<style lang="scss">
@use "@/styles/_mixins" as *;
@import "./Editor/style.scss";
$color-black: #000;
@ -392,7 +393,7 @@ $color-white: #eee;
border: 0;
color: $color-black;
padding: 0.2rem 0.5rem;
margin-right: 0.2rem;
@include margin-right(0.2rem);
border-radius: 3px;
cursor: pointer;
@ -464,7 +465,7 @@ $color-white: #eee;
ul,
ol {
padding-left: 1rem;
@include padding-left(1rem);
}
ul {
@ -480,7 +481,7 @@ $color-white: #eee;
blockquote {
border-left: 3px solid rgba($color-black, 0.1);
color: rgba($color-black, 0.8);
padding-left: 0.8rem;
@include padding-left(0.8rem);
font-style: italic;
p {

View file

@ -133,6 +133,7 @@ export default class EventCard extends Vue {
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
@use "@/styles/_event-card";
a.card {
@ -170,7 +171,7 @@ a.card {
position: absolute;
top: 10px;
right: 0;
margin-right: -3px;
@include margin-right(-3px);
z-index: 10;
max-width: 40%;
@ -214,7 +215,7 @@ a.card {
align-items: flex-end;
align-self: flex-start;
margin-bottom: 15px;
margin-left: 0rem;
@include margin-left(0);
}
& > .media-content {

View file

@ -128,6 +128,7 @@ export default class EventListViewCard extends mixins(ActorMixin, EventMixin) {
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
article.box {
div.content {
padding: 5px;
@ -148,7 +149,7 @@ article.box {
div.date-component {
flex: 0;
margin-right: 16px;
@include margin-right(16px);
}
.title {

View file

@ -152,10 +152,11 @@ export default class EventMap extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
.modal-card-head {
justify-content: flex-end;
button.delete {
margin-right: 1rem;
@include margin-right(1rem);
}
}

View file

@ -131,11 +131,12 @@ export default class EventMetadataItem extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
.card .media {
align-items: center;
& > button {
margin-left: 1rem;
@include margin-left(1rem);
}
}
</style>

View file

@ -131,6 +131,7 @@ export default class EventMinimalistCard extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
@use "@/styles/_event-card";
@import "~bulma/sass/utilities/mixins.sass";
@import "@/variables.scss";
@ -163,7 +164,7 @@ export default class EventMinimalistCard extends Vue {
}
.calendar-icon {
margin-right: 1rem;
@include margin-right(1rem);
}
.title-info-wrapper {

View file

@ -392,6 +392,7 @@ export default class EventParticipationCard extends mixins(
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
@use "@/styles/_event-card";
@import "~bulma/sass/utilities/mixins.sass";
@ -400,7 +401,7 @@ article.box {
position: absolute;
top: 10px;
right: 0;
margin-right: -5px;
@include margin-left(-5px);
z-index: 10;
max-width: 40%;
@ -516,7 +517,7 @@ article.box {
figure,
span.icon {
padding-right: 3px;
@include padding-right(3px);
}
}

View file

@ -121,6 +121,7 @@ export default class OrganizerPicker extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
::v-deep .list-item {
box-sizing: content-box;
@ -133,11 +134,11 @@ export default class OrganizerPicker extends Vue {
figure.image,
span.icon.media-left {
margin-right: 0.5rem;
@include margin-right(0.5rem);
}
span.icon.media-left {
margin-left: -0.25rem;
@include margin-left(-0.25rem);
}
}
}

View file

@ -86,6 +86,7 @@ export default class GroupMemberCard extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
.card {
.card-content {
display: flex;
@ -113,7 +114,7 @@ export default class GroupMemberCard extends Vue {
figure,
span.icon {
padding-right: 3px;
@include padding-right(3px);
}
}
}

View file

@ -33,6 +33,7 @@ export default class GroupSection extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
section {
display: flex;
flex-direction: column;
@ -44,7 +45,7 @@ section {
display: flex;
justify-content: flex-end;
padding-bottom: 0.5rem;
padding-right: 0.5rem;
@include padding-right(0.5rem);
}
.main-slot {
@ -68,7 +69,7 @@ div.group-section-title {
::v-deep & > a {
align-self: center;
margin-right: 5px;
@include margin-right(5px);
color: var(--title-color);
}

View file

@ -338,6 +338,7 @@ export default class NavBar extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
nav {
.navbar-item {
a.button {
@ -370,7 +371,7 @@ nav {
}
.navbar-item.has-dropdown a.navbar-link figure {
margin-right: 0.75rem;
@include margin-right(0.75rem);
display: flex;
align-items: center;
}

View file

@ -51,13 +51,14 @@
</template>
<style scoped lang="scss">
@use "@/styles/_mixins" as *;
.root {
display: flex;
align-items: center;
}
figure.image {
margin-right: 30px;
@include margin-right(30px);
max-height: 200px;
max-width: 200px;
overflow: hidden;
@ -99,7 +100,7 @@ figure.image {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin-right: 5px;
@include margin-right(5px);
}
}
}

View file

@ -71,6 +71,7 @@ export default class PostListItem extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
@import "~bulma/sass/utilities/mixins.sass";
.post-minimalist-card-wrapper {
@ -100,7 +101,7 @@ export default class PostListItem extends Vue {
}
::v-deep .icon {
vertical-align: middle;
margin-right: 5px;
@include margin-right(5px);
}
::v-deep .tags {

View file

@ -82,6 +82,7 @@ export default class ResourceItem extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
.resource-wrapper {
display: flex;
flex: 1;
@ -137,7 +138,7 @@ a {
display: inline-block;
width: 16px;
height: 16px;
margin-right: 6px;
@include margin-right(6px);
vertical-align: middle;
}

View file

@ -66,7 +66,8 @@ export default class Todo extends Vue {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
span.details {
margin-left: 1rem;
@include margin-left(1rem);
}
</style>

View file

@ -1,9 +1,11 @@
@use "@/styles/_mixins" as *;
.event-organizer {
display: flex;
align-items: center;
.organizer-name {
padding-left: 5px;
@include padding-left(5px);
font-weight: 600;
}
}
@ -13,6 +15,6 @@
align-items: center;
& > span:not(.icon) {
padding-left: 5px;
@include padding-left(5px);
}
}

View file

@ -0,0 +1,55 @@
@mixin margin($block-start, $inline-end, $block-end, $inline-start) {
@include margin-left($inline-start);
@include margin-right($inline-end);
margin-top: $block-start;
margin-bottom: $block-end;
}
@mixin padding($block-start, $inline-end, $block-end, $inline-start) {
@include padding-left($inline-start);
@include padding-right($inline-end);
padding-top: $block-start;
padding-bottom: $block-end;
}
@mixin margin-left($value) {
@supports (margin-inline-start: $value) {
margin-inline-start: $value;
}
@supports not (margin-inline-start: $value) {
margin-left: $value;
}
}
@mixin margin-right($value) {
@supports (margin-inline-end: $value) {
margin-inline-end: $value;
}
@supports not (margin-inline-end: $value) {
margin-right: $value;
}
}
@mixin padding-left($value) {
@supports (padding-inline-start: $value) {
padding-inline-start: $value;
}
@supports not (padding-inline-start: $value) {
padding-left: $value;
}
}
@mixin padding-right($value) {
@supports (padding-inline-end: $value) {
padding-inline-end: $value;
}
@supports not (padding-inline-end: $value) {
padding-right: $value;
}
}

View file

@ -215,7 +215,7 @@ h1 {
}
::v-deep .buttons > *:not(:last-child) .button {
margin-right: 0.5rem;
@include margin-right(0.5rem);
}
</style>

View file

@ -496,6 +496,7 @@ export default class Discussion extends mixins(GroupMixin) {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
div.container.section {
background: white;
padding: 1rem 5% 4rem;
@ -507,7 +508,7 @@ div.container.section {
h1.title {
margin-bottom: 0;
margin-right: 10px;
@include margin-right(10px);
}
form.title-edit {

View file

@ -459,6 +459,7 @@
</template>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
main section > .container {
background: $white;
@ -537,7 +538,7 @@ section {
.navbar-end {
justify-content: flex-end;
margin-left: auto;
@include margin-left(auto);
}
}
}

View file

@ -1151,6 +1151,7 @@ export default class Event extends EventMixin {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
.section {
padding: 1rem 2rem 4rem;
}
@ -1192,7 +1193,7 @@ div.sidebar {
span {
line-height: 2.7rem;
padding-right: 6px;
@include padding-right(6px);
}
}
}
@ -1239,7 +1240,7 @@ div.sidebar {
min-width: 20rem;
flex: 1;
@media all and (min-width: 672px) {
padding-left: 1rem;
@include padding-left(1rem);
}
.sticky {
@ -1281,7 +1282,7 @@ div.sidebar {
::v-deep blockquote {
border-left: 0.2em solid #333;
display: block;
padding-left: 1em;
@include padding-left(1rem);
}
::v-deep p {
@ -1327,7 +1328,7 @@ a.dropdown-item,
button.dropdown-item {
white-space: nowrap;
width: 100%;
padding-right: 1rem;
@include padding-right(1rem);
text-align: right;
}
@ -1362,7 +1363,7 @@ a.participations-link {
align-items: flex-end;
align-self: flex-start;
margin-bottom: 7px;
margin-left: 0rem;
@include margin-left(0);
}
}
.title {

View file

@ -1057,6 +1057,7 @@ export default class Group extends mixins(GroupMixin) {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
@import "~bulma/sass/utilities/mixins.sass";
div.container {
margin-bottom: 3rem;
@ -1074,7 +1075,7 @@ div.container {
.header .breadcrumb {
margin-bottom: 0.5rem;
margin-left: 0.5rem;
@include margin-left(0.5rem);
}
.block-container {
@ -1132,7 +1133,7 @@ div.container {
align-content: space-between;
& > span {
margin-right: 0.5rem;
@include margin-right(0.5rem);
}
}
@ -1165,10 +1166,10 @@ div.container {
margin: 0 0.5rem;
&:first-child {
margin-left: 0;
@include margin-left(0);
}
&:last-child {
margin-right: 0;
@include margin-right(0);
}
}
@ -1259,7 +1260,7 @@ div.container {
justify-content: center;
::v-deep .b-tooltip {
padding-right: 0.5em;
@include padding-right(0.5em);
}
}
@ -1274,7 +1275,7 @@ div.container {
}
figure:not(:first-child) {
margin-left: -10px;
@include margin-left(-10px);
}
}
}
@ -1291,9 +1292,9 @@ div.container {
.group-metadata {
min-width: 20rem;
flex: 1;
padding-left: 1rem;
@include padding-left(1rem);
@include mobile {
padding-left: 0;
@include padding-left(0);
}
.sticky {
@ -1330,7 +1331,7 @@ div.container {
.menu-dropdown {
::v-deep .dropdown-item,
::v-deep .has-link a {
padding-right: 1rem;
@include padding-right(1rem);
}
}

View file

@ -609,6 +609,7 @@ export default class Home extends Vue {
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
@import "~bulma/sass/utilities/mixins.sass";
main > div > .container {
@ -623,7 +624,7 @@ main > div > .container {
.events-recent {
& > h3 {
padding-left: 0.75rem;
@include padding-left(0.75rem);
}
.columns {
@ -637,7 +638,7 @@ main > div > .container {
margin: 0.5rem auto 1rem;
h3.subtitle {
margin-left: 7px;
@include margin-left(7px);
}
}

View file

@ -368,6 +368,7 @@ export default class EditPost extends mixins(GroupMixin, PostMixin) {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
.container.section {
background: $white;
}
@ -388,7 +389,7 @@ form {
.navbar-end {
justify-content: flex-end;
margin-left: auto;
@include margin-left(auto);
}
}
}

View file

@ -368,6 +368,7 @@ export default class Post extends mixins(GroupMixin, PostMixin) {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
article.post {
background: $white !important;
header {
@ -417,7 +418,7 @@ article.post {
flex-direction: column;
*:not(:first-child) {
padding-left: 5px;
@include padding-left(5px);
}
}
}
@ -478,7 +479,7 @@ article.post {
button.dropdown-item {
white-space: nowrap;
width: 100%;
padding-right: 1rem;
@include padding-right(1rem);
text-align: right;
}
}

View file

@ -754,6 +754,8 @@ export default class Resources extends Mixins(ResourceMixin) {
}
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
.container.section {
background: $white;
@ -766,7 +768,7 @@ nav.breadcrumb ul {
align-items: center;
li:last-child .dropdown {
margin-left: 5px;
@include margin-left(5px);
a {
justify-content: left;
@ -785,14 +787,14 @@ nav.breadcrumb ul {
align-items: center;
::v-deep .b-checkbox.checkbox {
margin-left: 10px;
@include margin-left(10px);
}
.actions {
margin-right: 5px;
@include margin-right(5px);
& > * {
margin-left: 5px;
@include margin-left(5px);
}
}
}
@ -810,11 +812,11 @@ nav.breadcrumb ul {
.resource-checkbox {
align-self: center;
padding-left: 10px;
@include padding-left(10px);
opacity: 0.3;
::v-deep .b-checkbox.checkbox {
margin-right: 0.25rem;
@include margin-right(0.25rem);
}
}

View file

@ -780,6 +780,7 @@ export default class Notifications extends Vue {
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
.field {
&:not(:last-child) {
margin-bottom: 1.5rem;
@ -790,11 +791,12 @@ export default class Notifications extends Vue {
text-decoration: underline;
text-decoration-color: #fea72b;
text-decoration-thickness: 2px;
margin-left: 5px;
@include margin-left(5px);
}
}
::v-deep .buttons > *:not(:last-child) .button {
margin-right: 0.5rem;
@include margin-right(0.5rem);
}
</style>

View file

@ -42,7 +42,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
target_type
|> String.to_existing_atom()
|> transform_action_log(action, action_log)
|> Map.merge(%{actor: actor, id: id, inserted_at: inserted_at})
|> add_extra_data(actor, id, inserted_at)
end)
|> Enum.filter(& &1)
@ -54,6 +54,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
{:error, dgettext("errors", "You need to be logged-in and a moderator to list action logs")}
end
defp add_extra_data(nil, _actor, _id, _inserted_at), do: nil
defp add_extra_data(map, actor, id, inserted_at) do
Map.merge(map, %{actor: actor, id: id, inserted_at: inserted_at})
end
@spec transform_action_log(module(), atom(), ActionLog.t()) :: map()
defp transform_action_log(
Report,
@ -127,22 +133,22 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
# Changes are stored as %{"key" => "value"} so we need to convert them back as struct
@spec convert_changes_to_struct(module(), map()) :: struct()
defp convert_changes_to_struct(struct, %{"report_id" => _report_id} = changes) do
with data <- for({key, val} <- changes, into: %{}, do: {String.to_existing_atom(key), val}),
data <- Map.put(data, :report, Mobilizon.Reports.get_report(data.report_id)) do
struct(struct, data)
end
data = for({key, val} <- changes, into: %{}, do: {String.to_existing_atom(key), val})
data = Map.put(data, :report, Mobilizon.Reports.get_report(data.report_id))
struct(struct, data)
end
defp convert_changes_to_struct(struct, changes) do
with changeset <- struct.__changeset__,
data <-
for(
{key, val} <- changes,
into: %{},
do: {String.to_existing_atom(key), process_eventual_type(changeset, key, val)}
) do
struct(struct, data)
end
changeset = struct.__changeset__
data =
for(
{key, val} <- changes,
into: %{},
do: {String.to_existing_atom(key), process_eventual_type(changeset, key, val)}
)
struct(struct, data)
end
# datetimes are not unserialized as DateTime/NaiveDateTime so we do it manually with changeset data
@ -150,6 +156,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
DateTime.t() | NaiveDateTime.t() | any()
defp process_eventual_type(changeset, key, val) do
cond do
changeset[String.to_existing_atom(key)] == Mobilizon.Actors.ActorType and not is_nil(val) ->
String.to_existing_atom(val)
changeset[String.to_existing_atom(key)] == :utc_datetime and not is_nil(val) ->
{:ok, datetime, _} = DateTime.from_iso8601(val)
datetime

View file

@ -64,13 +64,13 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
%Comment{}, _ ->
:comment
%Actor{type: "Person"}, _ ->
%Actor{type: :Person}, _ ->
:person
%User{}, _ ->
:user
%Actor{type: "Group"}, _ ->
%Actor{type: :Group}, _ ->
:group
_, _ ->

View file

@ -112,18 +112,35 @@ defmodule Mobilizon.Service.Export.ICalendar do
@spec do_export_event(Event.t()) :: ICalendar.Event.t()
defp do_export_event(%Event{} = event) do
%ICalendar.Event{
icalendar_event = %ICalendar.Event{
summary: event.title,
dtstart: begins_on(event),
dtstamp: event.publish_at || DateTime.utc_now(),
dtend: ends_on(event),
description: HTML.strip_tags(event.description),
uid: event.uuid,
url: event.url,
geo: Address.coords(event.physical_address),
location: Address.representation(event.physical_address),
categories: event.tags |> Enum.map(& &1.title)
url: event.url
}
icalendar_event =
if event.physical_address do
%ICalendar.Event{
icalendar_event
| geo: Address.coords(event.physical_address),
location: Address.representation(event.physical_address)
}
else
icalendar_event
end
icalendar_event =
if length(event.tags) > 0 do
%ICalendar.Event{icalendar_event | categories: event.tags |> Enum.map(& &1.title)}
else
icalendar_event
end
icalendar_event
end
@spec vendor :: String.t()