diff --git a/js/public/index.html b/js/public/index.html index 6535abfcd..083951877 100644 --- a/js/public/index.html +++ b/js/public/index.html @@ -1,5 +1,5 @@ - + diff --git a/js/src/App.vue b/js/src/App.vue index 237ab57d9..cafe7ffe1 100644 --- a/js/src/App.vue +++ b/js/src/App.vue @@ -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 { diff --git a/js/src/common.scss b/js/src/common.scss index b9c39647d..9566e8925 100644 --- a/js/src/common.scss +++ b/js/src/common.scss @@ -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 { diff --git a/js/src/components/Account/ActorCard.vue b/js/src/components/Account/ActorCard.vue index a57c2692a..2b7018e88 100644 --- a/js/src/components/Account/ActorCard.vue +++ b/js/src/components/Account/ActorCard.vue @@ -53,6 +53,7 @@ export default class ActorCard extends Vue { diff --git a/js/src/components/Comment/Comment.vue b/js/src/components/Comment/Comment.vue index 33fd0cc92..5ca556ea7 100644 --- a/js/src/components/Comment/Comment.vue +++ b/js/src/components/Comment/Comment.vue @@ -336,6 +336,7 @@ export default class Comment extends Vue { } diff --git a/js/src/components/Event/EventMinimalistCard.vue b/js/src/components/Event/EventMinimalistCard.vue index 631c286ae..09443f91f 100644 --- a/js/src/components/Event/EventMinimalistCard.vue +++ b/js/src/components/Event/EventMinimalistCard.vue @@ -131,6 +131,7 @@ export default class EventMinimalistCard extends Vue { } diff --git a/js/src/styles/_event-card.scss b/js/src/styles/_event-card.scss index f657bc47d..4854de21b 100644 --- a/js/src/styles/_event-card.scss +++ b/js/src/styles/_event-card.scss @@ -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); } } diff --git a/js/src/styles/_mixins.scss b/js/src/styles/_mixins.scss new file mode 100644 index 000000000..040d3ae82 --- /dev/null +++ b/js/src/styles/_mixins.scss @@ -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; + } +} diff --git a/js/src/views/Account/children/EditIdentity.vue b/js/src/views/Account/children/EditIdentity.vue index 5d4e5f5e7..5395cdb49 100644 --- a/js/src/views/Account/children/EditIdentity.vue +++ b/js/src/views/Account/children/EditIdentity.vue @@ -215,7 +215,7 @@ h1 { } ::v-deep .buttons > *:not(:last-child) .button { - margin-right: 0.5rem; + @include margin-right(0.5rem); } diff --git a/js/src/views/Discussions/Discussion.vue b/js/src/views/Discussions/Discussion.vue index a016318d1..20fe5f6a9 100644 --- a/js/src/views/Discussions/Discussion.vue +++ b/js/src/views/Discussions/Discussion.vue @@ -496,6 +496,7 @@ export default class Discussion extends mixins(GroupMixin) { } diff --git a/lib/graphql/resolvers/admin.ex b/lib/graphql/resolvers/admin.ex index efaccaad1..36857e7dd 100644 --- a/lib/graphql/resolvers/admin.ex +++ b/lib/graphql/resolvers/admin.ex @@ -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 diff --git a/lib/graphql/schema/admin.ex b/lib/graphql/schema/admin.ex index 057548d84..dfe02c093 100644 --- a/lib/graphql/schema/admin.ex +++ b/lib/graphql/schema/admin.ex @@ -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 _, _ -> diff --git a/lib/service/export/icalendar.ex b/lib/service/export/icalendar.ex index 40e5e2a90..9a75c308a 100644 --- a/lib/service/export/icalendar.ex +++ b/lib/service/export/icalendar.ex @@ -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()