From 0d081bc47ebee4d3336727dbb6c074c008bc08dd Mon Sep 17 00:00:00 2001 From: Athou Date: Sun, 14 Apr 2024 11:26:39 +0200 Subject: [PATCH] add button in the header to star entry (#1025) --- commafeed-client/src/app/constants.ts | 3 + commafeed-client/src/app/entries/thunks.ts | 20 ++++--- commafeed-client/src/app/types.ts | 4 ++ commafeed-client/src/app/user/slice.ts | 12 ++++ commafeed-client/src/app/user/thunks.ts | 18 +++++- .../src/components/ActionButton.tsx | 3 +- .../src/components/RelativeDate.tsx | 3 +- .../src/components/content/FeedEntry.tsx | 28 +++++++++- .../content/header/FeedEntryCompactHeader.tsx | 6 +- .../content/header/FeedEntryHeader.tsx | 31 +++++----- .../content/header/OpenExternalLink.tsx | 5 +- .../src/components/content/header/Star.tsx | 29 ++++++++++ .../components/settings/DisplaySettings.tsx | 56 ++++++++++++++++--- .../src/components/sidebar/UnreadCount.tsx | 3 +- .../commafeed/backend/model/UserSettings.java | 12 ++++ .../commafeed/frontend/model/Settings.java | 12 ++++ .../commafeed/frontend/resource/UserREST.java | 5 ++ .../resources/changelogs/db.changelog-4.4.xml | 17 ++++++ .../src/main/resources/migrations.xml | 1 + 19 files changed, 229 insertions(+), 39 deletions(-) create mode 100644 commafeed-client/src/components/content/header/Star.tsx create mode 100644 commafeed-server/src/main/resources/changelogs/db.changelog-4.4.xml diff --git a/commafeed-client/src/app/constants.ts b/commafeed-client/src/app/constants.ts index 890b334b..2bf8903e 100644 --- a/commafeed-client/src/app/constants.ts +++ b/commafeed-client/src/app/constants.ts @@ -104,6 +104,9 @@ export const Constants = { entryId: (entry: Entry) => `entry-id-${entry.id}`, entryContextMenuId: (entry: Entry) => entry.id, }, + tooltip: { + delay: 500, + }, browserExtensionUrl: "https://github.com/Athou/commafeed-browser-extension", bitcoinWalletAddress: "1dymfUxqCWpyD7a6rQSqNy4rLVDBsAr5e", } diff --git a/commafeed-client/src/app/entries/thunks.ts b/commafeed-client/src/app/entries/thunks.ts index 82f25af2..5484b36b 100644 --- a/commafeed-client/src/app/entries/thunks.ts +++ b/commafeed-client/src/app/entries/thunks.ts @@ -113,13 +113,19 @@ export const markAllEntries = createAppAsyncThunk( thunkApi.dispatch(reloadTree()) } ) -export const starEntry = createAppAsyncThunk("entries/entry/star", (arg: { entry: Entry; starred: boolean }) => { - client.entry.star({ - id: arg.entry.id, - feedId: +arg.entry.feedId, - starred: arg.starred, - }) -}) +export const starEntry = createAppAsyncThunk( + "entries/entry/star", + (arg: { entry: Entry; starred: boolean }) => { + client.entry.star({ + id: arg.entry.id, + feedId: +arg.entry.feedId, + starred: arg.starred, + }) + }, + { + condition: arg => arg.entry.markable && arg.entry.starred !== arg.starred, + } +) export const selectEntry = createAppAsyncThunk( "entries/entry/select", ( diff --git a/commafeed-client/src/app/types.ts b/commafeed-client/src/app/types.ts index b57369ba..e782deee 100644 --- a/commafeed-client/src/app/types.ts +++ b/commafeed-client/src/app/types.ts @@ -6,6 +6,8 @@ export type ViewMode = "title" | "cozy" | "detailed" | "expanded" export type ScrollMode = "always" | "never" | "if_needed" +export type IconDisplayMode = "always" | "never" | "on_desktop" | "on_mobile" + export interface AddCategoryRequest { name: string parentId?: string @@ -242,6 +244,8 @@ export interface Settings { customJs?: string scrollSpeed: number scrollMode: ScrollMode + starIconDisplayMode: IconDisplayMode + externalLinkIconDisplayMode: IconDisplayMode markAllAsReadConfirmation: boolean customContextMenu: boolean mobileFooter: boolean diff --git a/commafeed-client/src/app/user/slice.ts b/commafeed-client/src/app/user/slice.ts index bafe5639..0f125ea7 100644 --- a/commafeed-client/src/app/user/slice.ts +++ b/commafeed-client/src/app/user/slice.ts @@ -4,6 +4,7 @@ import { createSlice, isAnyOf } from "@reduxjs/toolkit" import { type Settings, type UserModel } from "app/types" import { changeCustomContextMenu, + changeExternalLinkIconDisplayMode, changeLanguage, changeMarkAllAsReadConfirmation, changeMobileFooter, @@ -14,6 +15,7 @@ import { changeScrollSpeed, changeSharingSetting, changeShowRead, + changeStarIconDisplayMode, reloadProfile, reloadSettings, reloadTags, @@ -69,6 +71,14 @@ export const userSlice = createSlice({ if (!state.settings) return state.settings.scrollMode = action.meta.arg }) + builder.addCase(changeStarIconDisplayMode.pending, (state, action) => { + if (!state.settings) return + state.settings.starIconDisplayMode = action.meta.arg + }) + builder.addCase(changeExternalLinkIconDisplayMode.pending, (state, action) => { + if (!state.settings) return + state.settings.externalLinkIconDisplayMode = action.meta.arg + }) builder.addCase(changeMarkAllAsReadConfirmation.pending, (state, action) => { if (!state.settings) return state.settings.markAllAsReadConfirmation = action.meta.arg @@ -92,6 +102,8 @@ export const userSlice = createSlice({ changeShowRead.fulfilled, changeScrollMarks.fulfilled, changeScrollMode.fulfilled, + changeStarIconDisplayMode.fulfilled, + changeExternalLinkIconDisplayMode.fulfilled, changeMarkAllAsReadConfirmation.fulfilled, changeCustomContextMenu.fulfilled, changeMobileFooter.fulfilled, diff --git a/commafeed-client/src/app/user/thunks.ts b/commafeed-client/src/app/user/thunks.ts index fa6a25fb..12c2a553 100644 --- a/commafeed-client/src/app/user/thunks.ts +++ b/commafeed-client/src/app/user/thunks.ts @@ -1,7 +1,7 @@ import { createAppAsyncThunk } from "app/async-thunk" import { client } from "app/client" import { reloadEntries } from "app/entries/thunks" -import type { ReadingMode, ReadingOrder, ScrollMode, SharingSettings } from "app/types" +import type { IconDisplayMode, ReadingMode, ReadingOrder, ScrollMode, SharingSettings } from "app/types" export const reloadSettings = createAppAsyncThunk("settings/reload", async () => await client.user.getSettings().then(r => r.data)) export const reloadProfile = createAppAsyncThunk("profile/reload", async () => await client.user.getProfile().then(r => r.data)) @@ -43,6 +43,22 @@ export const changeScrollMode = createAppAsyncThunk("settings/scrollMode", (scro if (!settings) return client.user.saveSettings({ ...settings, scrollMode }) }) +export const changeStarIconDisplayMode = createAppAsyncThunk( + "settings/starIconDisplayMode", + (starIconDisplayMode: IconDisplayMode, thunkApi) => { + const { settings } = thunkApi.getState().user + if (!settings) return + client.user.saveSettings({ ...settings, starIconDisplayMode }) + } +) +export const changeExternalLinkIconDisplayMode = createAppAsyncThunk( + "settings/externalLinkIconDisplayMode", + (externalLinkIconDisplayMode: IconDisplayMode, thunkApi) => { + const { settings } = thunkApi.getState().user + if (!settings) return + client.user.saveSettings({ ...settings, externalLinkIconDisplayMode }) + } +) export const changeMarkAllAsReadConfirmation = createAppAsyncThunk( "settings/markAllAsReadConfirmation", (markAllAsReadConfirmation: boolean, thunkApi) => { diff --git a/commafeed-client/src/components/ActionButton.tsx b/commafeed-client/src/components/ActionButton.tsx index 2d660741..fdebdc8e 100644 --- a/commafeed-client/src/components/ActionButton.tsx +++ b/commafeed-client/src/components/ActionButton.tsx @@ -1,5 +1,6 @@ import { ActionIcon, Button, type ButtonVariant, Tooltip, useMantineTheme } from "@mantine/core" import { type ActionIconVariant } from "@mantine/core/lib/components/ActionIcon/ActionIcon" +import { Constants } from "app/constants" import { useActionButton } from "hooks/useActionButton" import { forwardRef, type MouseEventHandler, type ReactNode } from "react" @@ -22,7 +23,7 @@ export const ActionButton = forwardRef((pr const variant = props.variant ?? "subtle" const iconOnly = (mobile && !props.showLabelOnMobile) || (!mobile && props.hideLabelOnDesktop) return iconOnly ? ( - + {props.icon} diff --git a/commafeed-client/src/components/RelativeDate.tsx b/commafeed-client/src/components/RelativeDate.tsx index b043f9fa..8e3f7ed7 100644 --- a/commafeed-client/src/components/RelativeDate.tsx +++ b/commafeed-client/src/components/RelativeDate.tsx @@ -1,5 +1,6 @@ import { Trans } from "@lingui/macro" import { Tooltip } from "@mantine/core" +import { Constants } from "app/constants" import dayjs from "dayjs" import { useEffect, useState } from "react" @@ -13,7 +14,7 @@ export function RelativeDate(props: { date: Date | number | undefined }) { if (!props.date) return N/A const date = dayjs(props.date) return ( - + {date.from(dayjs(now))} ) diff --git a/commafeed-client/src/components/content/FeedEntry.tsx b/commafeed-client/src/components/content/FeedEntry.tsx index 39dc45f6..b8763cff 100644 --- a/commafeed-client/src/components/content/FeedEntry.tsx +++ b/commafeed-client/src/components/content/FeedEntry.tsx @@ -1,8 +1,10 @@ import { Box, Divider, type MantineRadius, type MantineSpacing, Paper } from "@mantine/core" import { Constants } from "app/constants" +import { useAppSelector } from "app/store" import { type Entry, type ViewMode } from "app/types" import { FeedEntryCompactHeader } from "components/content/header/FeedEntryCompactHeader" import { FeedEntryHeader } from "components/content/header/FeedEntryHeader" +import { useMobile } from "hooks/useMobile" import { useViewMode } from "hooks/useViewMode" import React from "react" import { useSwipeable } from "react-swipeable" @@ -103,6 +105,15 @@ export function FeedEntry(props: FeedEntryProps) { maxWidth: props.maxWidth, }) + const externalLinkDisplayMode = useAppSelector(state => state.user.settings?.externalLinkIconDisplayMode) + const starIconDisplayMode = useAppSelector(state => state.user.settings?.starIconDisplayMode) + const mobile = useMobile() + + const showExternalLinkIcon = + externalLinkDisplayMode && ["always", mobile ? "on_mobile" : "on_desktop"].includes(externalLinkDisplayMode) + const showStarIcon = + props.entry.markable && starIconDisplayMode && ["always", mobile ? "on_mobile" : "on_desktop"].includes(starIconDisplayMode) + const swipeHandlers = useSwipeable({ onSwipedLeft: props.onSwipedLeft, }) @@ -147,8 +158,21 @@ export function FeedEntry(props: FeedEntryProps) { onContextMenu={props.onHeaderRightClick} > - {compactHeader && } - {!compactHeader && } + {compactHeader && ( + + )} + {!compactHeader && ( + + )} {props.expanded && ( diff --git a/commafeed-client/src/components/content/header/FeedEntryCompactHeader.tsx b/commafeed-client/src/components/content/header/FeedEntryCompactHeader.tsx index ceb770e5..f1e52143 100644 --- a/commafeed-client/src/components/content/header/FeedEntryCompactHeader.tsx +++ b/commafeed-client/src/components/content/header/FeedEntryCompactHeader.tsx @@ -2,6 +2,7 @@ import { Box, Text } from "@mantine/core" import { type Entry } from "app/types" import { FeedFavicon } from "components/content/FeedFavicon" import { OpenExternalLink } from "components/content/header/OpenExternalLink" +import { Star } from "components/content/header/Star" import { RelativeDate } from "components/RelativeDate" import { OnDesktop } from "components/responsive/OnDesktop" import { tss } from "tss" @@ -9,6 +10,8 @@ import { FeedEntryTitle } from "./FeedEntryTitle" export interface FeedEntryHeaderProps { entry: Entry + showStarIcon?: boolean + showExternalLinkIcon?: boolean } const useStyles = tss @@ -46,6 +49,7 @@ export function FeedEntryCompactHeader(props: FeedEntryHeaderProps) { }) return ( + {props.showStarIcon && } @@ -62,7 +66,7 @@ export function FeedEntryCompactHeader(props: FeedEntryHeaderProps) { - + {props.showExternalLinkIcon && } ) } diff --git a/commafeed-client/src/components/content/header/FeedEntryHeader.tsx b/commafeed-client/src/components/content/header/FeedEntryHeader.tsx index 48598c54..d2584cb3 100644 --- a/commafeed-client/src/components/content/header/FeedEntryHeader.tsx +++ b/commafeed-client/src/components/content/header/FeedEntryHeader.tsx @@ -1,7 +1,8 @@ -import { Box, Space, Text } from "@mantine/core" +import { Box, Flex, Space, Text } from "@mantine/core" import { type Entry } from "app/types" import { FeedFavicon } from "components/content/FeedFavicon" import { OpenExternalLink } from "components/content/header/OpenExternalLink" +import { Star } from "components/content/header/Star" import { RelativeDate } from "components/RelativeDate" import { tss } from "tss" import { FeedEntryTitle } from "./FeedEntryTitle" @@ -9,6 +10,8 @@ import { FeedEntryTitle } from "./FeedEntryTitle" export interface FeedEntryHeaderProps { entry: Entry expanded: boolean + showStarIcon?: boolean + showExternalLinkIcon?: boolean } const useStyles = tss @@ -17,16 +20,9 @@ const useStyles = tss }>() .create(({ colorScheme, read }) => ({ main: { - display: "flex", - alignItems: "flex-start", - justifyContent: "space-between", - }, - mainText: { fontWeight: colorScheme === "light" && !read ? "bold" : "inherit", }, details: { - display: "flex", - alignItems: "center", fontSize: "90%", }, })) @@ -37,13 +33,18 @@ export function FeedEntryHeader(props: FeedEntryHeaderProps) { }) return ( - - + + + {props.showStarIcon && ( + + + + )} - - - - + + {props.showExternalLinkIcon && } + + @@ -51,7 +52,7 @@ export function FeedEntryHeader(props: FeedEntryHeaderProps) { ยท - + {props.expanded && ( diff --git a/commafeed-client/src/components/content/header/OpenExternalLink.tsx b/commafeed-client/src/components/content/header/OpenExternalLink.tsx index bc848111..b8db4082 100644 --- a/commafeed-client/src/components/content/header/OpenExternalLink.tsx +++ b/commafeed-client/src/components/content/header/OpenExternalLink.tsx @@ -1,5 +1,6 @@ import { Trans } from "@lingui/macro" import { ActionIcon, Anchor, Tooltip } from "@mantine/core" +import { Constants } from "app/constants" import { markEntry } from "app/entries/thunks" import { useAppDispatch } from "app/store" import { type Entry } from "app/types" @@ -19,9 +20,9 @@ export function OpenExternalLink(props: { entry: Entry }) { return ( - Open link}> + Open link} openDelay={Constants.tooltip.delay}> - + diff --git a/commafeed-client/src/components/content/header/Star.tsx b/commafeed-client/src/components/content/header/Star.tsx new file mode 100644 index 00000000..6e683832 --- /dev/null +++ b/commafeed-client/src/components/content/header/Star.tsx @@ -0,0 +1,29 @@ +import { Trans } from "@lingui/macro" +import { ActionIcon, Tooltip } from "@mantine/core" +import { Constants } from "app/constants" +import { starEntry } from "app/entries/thunks" +import { useAppDispatch } from "app/store" +import type { Entry } from "app/types" +import { TbStar, TbStarFilled } from "react-icons/tb" + +export function Star(props: { entry: Entry }) { + const dispatch = useAppDispatch() + const onClick = (e: React.MouseEvent) => { + e.stopPropagation() + e.preventDefault() + dispatch( + starEntry({ + entry: props.entry, + starred: !props.entry.starred, + }) + ) + } + + return ( + Unstar : Star} openDelay={Constants.tooltip.delay}> + + {props.entry.starred ? : } + + + ) +} diff --git a/commafeed-client/src/components/settings/DisplaySettings.tsx b/commafeed-client/src/components/settings/DisplaySettings.tsx index 0c0942b1..38007ce6 100644 --- a/commafeed-client/src/components/settings/DisplaySettings.tsx +++ b/commafeed-client/src/components/settings/DisplaySettings.tsx @@ -1,10 +1,12 @@ -import { Trans } from "@lingui/macro" +import { t, Trans } from "@lingui/macro" import { Divider, Group, Radio, Select, SimpleGrid, Stack, Switch } from "@mantine/core" +import { type ComboboxData } from "@mantine/core/lib/components/Combobox/Combobox.types" import { Constants } from "app/constants" import { useAppDispatch, useAppSelector } from "app/store" -import { type ScrollMode, type SharingSettings } from "app/types" +import { type IconDisplayMode, type ScrollMode, type SharingSettings } from "app/types" import { changeCustomContextMenu, + changeExternalLinkIconDisplayMode, changeLanguage, changeMarkAllAsReadConfirmation, changeMobileFooter, @@ -13,16 +15,38 @@ import { changeScrollSpeed, changeSharingSetting, changeShowRead, + changeStarIconDisplayMode, } from "app/user/thunks" import { locales } from "i18n" import { type ReactNode } from "react" +const displayModeData: ComboboxData = [ + { + value: "always", + label: t`Always`, + }, + { + value: "on_desktop", + label: t`On desktop`, + }, + { + value: "on_mobile", + label: t`On mobile`, + }, + { + value: "never", + label: t`Never`, + }, +] + export function DisplaySettings() { const language = useAppSelector(state => state.user.settings?.language) const scrollSpeed = useAppSelector(state => state.user.settings?.scrollSpeed) const showRead = useAppSelector(state => state.user.settings?.showRead) const scrollMarks = useAppSelector(state => state.user.settings?.scrollMarks) const scrollMode = useAppSelector(state => state.user.settings?.scrollMode) + const starIconDisplayMode = useAppSelector(state => state.user.settings?.starIconDisplayMode) + const externalLinkIconDisplayMode = useAppSelector(state => state.user.settings?.externalLinkIconDisplayMode) const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation) const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu) const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter) @@ -59,18 +83,34 @@ export function DisplaySettings() { onChange={async e => await dispatch(changeMarkAllAsReadConfirmation(e.currentTarget.checked))} /> - Show CommaFeed's own context menu on right click} - checked={customContextMenu} - onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))} - /> - On mobile, show action buttons at the bottom of the screen} checked={mobileFooter} onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))} /> + Entry headers} labelPosition="center" /> + + Show external link icon} + value={externalLinkIconDisplayMode} + data={displayModeData} + onChange={async s => await dispatch(changeExternalLinkIconDisplayMode(s as IconDisplayMode))} + /> + + Show CommaFeed's own context menu on right click} + checked={customContextMenu} + onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))} + /> + Scrolling} labelPosition="center" /> ({ @@ -16,7 +17,7 @@ export function UnreadCount(props: { unreadCount: number }) { const count = props.unreadCount >= 10000 ? "10k+" : props.unreadCount return ( - + {count} diff --git a/commafeed-server/src/main/java/com/commafeed/backend/model/UserSettings.java b/commafeed-server/src/main/java/com/commafeed/backend/model/UserSettings.java index 7a09b6f3..886e7b8d 100644 --- a/commafeed-server/src/main/java/com/commafeed/backend/model/UserSettings.java +++ b/commafeed-server/src/main/java/com/commafeed/backend/model/UserSettings.java @@ -39,6 +39,10 @@ public class UserSettings extends AbstractModel { always, never, if_needed } + public enum IconDisplayMode { + always, never, on_desktop, on_mobile + } + @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false, unique = true) private User user; @@ -74,6 +78,14 @@ public class UserSettings extends AbstractModel { @Column(nullable = false) private ScrollMode scrollMode; + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private IconDisplayMode starIconDisplayMode; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private IconDisplayMode externalLinkIconDisplayMode; + private boolean markAllAsReadConfirmation; private boolean customContextMenu; private boolean mobileFooter; diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/model/Settings.java b/commafeed-server/src/main/java/com/commafeed/frontend/model/Settings.java index fd7c8158..28850422 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/model/Settings.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/model/Settings.java @@ -47,6 +47,18 @@ public class Settings implements Serializable { requiredMode = RequiredMode.REQUIRED) private String scrollMode; + @Schema( + description = "whether to show the star icon in the header of entries", + allowableValues = "always,never,on_desktop,on_mobile", + requiredMode = RequiredMode.REQUIRED) + private String starIconDisplayMode; + + @Schema( + description = "whether to show the external link icon in the header of entries", + allowableValues = "always,never,on_desktop,on_mobile", + requiredMode = RequiredMode.REQUIRED) + private String externalLinkIconDisplayMode; + @Schema(description = "ask for confirmation when marking all entries as read", requiredMode = RequiredMode.REQUIRED) private boolean markAllAsReadConfirmation; diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/resource/UserREST.java b/commafeed-server/src/main/java/com/commafeed/frontend/resource/UserREST.java index 58a9695d..6aab7fdb 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/resource/UserREST.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/resource/UserREST.java @@ -22,6 +22,7 @@ import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserRole; import com.commafeed.backend.model.UserRole.Role; import com.commafeed.backend.model.UserSettings; +import com.commafeed.backend.model.UserSettings.IconDisplayMode; import com.commafeed.backend.model.UserSettings.ReadingMode; import com.commafeed.backend.model.UserSettings.ReadingOrder; import com.commafeed.backend.model.UserSettings.ScrollMode; @@ -110,6 +111,8 @@ public class UserREST { s.setLanguage(settings.getLanguage()); s.setScrollSpeed(settings.getScrollSpeed()); s.setScrollMode(settings.getScrollMode().name()); + s.setStarIconDisplayMode(settings.getStarIconDisplayMode().name()); + s.setExternalLinkIconDisplayMode(settings.getExternalLinkIconDisplayMode().name()); s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation()); s.setCustomContextMenu(settings.isCustomContextMenu()); s.setMobileFooter(settings.isMobileFooter()); @@ -131,6 +134,8 @@ public class UserREST { s.setLanguage("en"); s.setScrollSpeed(400); s.setScrollMode(ScrollMode.if_needed.name()); + s.setStarIconDisplayMode(IconDisplayMode.always.name()); + s.setExternalLinkIconDisplayMode(IconDisplayMode.always.name()); s.setMarkAllAsReadConfirmation(true); s.setCustomContextMenu(true); s.setMobileFooter(false); diff --git a/commafeed-server/src/main/resources/changelogs/db.changelog-4.4.xml b/commafeed-server/src/main/resources/changelogs/db.changelog-4.4.xml new file mode 100644 index 00000000..e614d771 --- /dev/null +++ b/commafeed-server/src/main/resources/changelogs/db.changelog-4.4.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + diff --git a/commafeed-server/src/main/resources/migrations.xml b/commafeed-server/src/main/resources/migrations.xml index fc4cbc5c..8b17f7a0 100644 --- a/commafeed-server/src/main/resources/migrations.xml +++ b/commafeed-server/src/main/resources/migrations.xml @@ -30,5 +30,6 @@ + \ No newline at end of file