forked from Archives/Athou_commafeed
Add user preference to disable sidebar swipe-to-open on mobile; cleanup migrations + README in prep for long-term fork maintenance
This commit is contained in:
6
README-fork.md
Normal file
6
README-fork.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# `garrettmills/commafeed`
|
||||||
|
|
||||||
|
This is my personal fork of `Athou/commafeed` with some tweaks:
|
||||||
|
|
||||||
|
- "Infrequent" tab - like "All" but limits to blogs w/ an average post interval greater than a user-configurable number of days
|
||||||
|
- User preference to disable the swipe-to-open-menu gesture on mobile
|
||||||
@@ -285,6 +285,7 @@ export interface Settings {
|
|||||||
unreadCountTitle: boolean
|
unreadCountTitle: boolean
|
||||||
unreadCountFavicon: boolean
|
unreadCountFavicon: boolean
|
||||||
disablePullToRefresh: boolean
|
disablePullToRefresh: boolean
|
||||||
|
disableMobileSwipe: boolean
|
||||||
infrequentThresholdDays: number
|
infrequentThresholdDays: number
|
||||||
primaryColor?: string
|
primaryColor?: string
|
||||||
sharingSettings: SharingSettings
|
sharingSettings: SharingSettings
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { createSlice, isAnyOf, type PayloadAction } from "@reduxjs/toolkit"
|
|||||||
import type { LocalSettings, Settings, UserModel, ViewMode } from "@/app/types"
|
import type { LocalSettings, Settings, UserModel, ViewMode } from "@/app/types"
|
||||||
import {
|
import {
|
||||||
changeCustomContextMenu,
|
changeCustomContextMenu,
|
||||||
|
changeDisableMobileSwipe,
|
||||||
changeDisablePullToRefresh,
|
changeDisablePullToRefresh,
|
||||||
changeEntriesToKeepOnTopWhenScrolling,
|
changeEntriesToKeepOnTopWhenScrolling,
|
||||||
changeExternalLinkIconDisplayMode,
|
changeExternalLinkIconDisplayMode,
|
||||||
@@ -142,6 +143,10 @@ export const userSlice = createSlice({
|
|||||||
if (!state.settings) return
|
if (!state.settings) return
|
||||||
state.settings.disablePullToRefresh = action.meta.arg
|
state.settings.disablePullToRefresh = action.meta.arg
|
||||||
})
|
})
|
||||||
|
builder.addCase(changeDisableMobileSwipe.pending, (state, action) => {
|
||||||
|
if (!state.settings) return
|
||||||
|
state.settings.disableMobileSwipe = action.meta.arg
|
||||||
|
})
|
||||||
builder.addCase(changeInfrequentThresholdDays.pending, (state, action) => {
|
builder.addCase(changeInfrequentThresholdDays.pending, (state, action) => {
|
||||||
if (!state.settings) return
|
if (!state.settings) return
|
||||||
state.settings.infrequentThresholdDays = action.meta.arg
|
state.settings.infrequentThresholdDays = action.meta.arg
|
||||||
@@ -176,6 +181,7 @@ export const userSlice = createSlice({
|
|||||||
changeUnreadCountTitle.fulfilled,
|
changeUnreadCountTitle.fulfilled,
|
||||||
changeUnreadCountFavicon.fulfilled,
|
changeUnreadCountFavicon.fulfilled,
|
||||||
changeDisablePullToRefresh.fulfilled,
|
changeDisablePullToRefresh.fulfilled,
|
||||||
|
changeDisableMobileSwipe.fulfilled,
|
||||||
changeInfrequentThresholdDays.fulfilled,
|
changeInfrequentThresholdDays.fulfilled,
|
||||||
changePrimaryColor.fulfilled,
|
changePrimaryColor.fulfilled,
|
||||||
changeSharingSetting.fulfilled,
|
changeSharingSetting.fulfilled,
|
||||||
|
|||||||
@@ -131,6 +131,12 @@ export const changeDisablePullToRefresh = createAppAsyncThunk(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const changeDisableMobileSwipe = createAppAsyncThunk("settings/disableMobileSwipe", (disableMobileSwipe: boolean, thunkApi) => {
|
||||||
|
const { settings } = thunkApi.getState().user
|
||||||
|
if (!settings) return
|
||||||
|
client.user.saveSettings({ ...settings, disableMobileSwipe })
|
||||||
|
})
|
||||||
|
|
||||||
export const changePrimaryColor = createAppAsyncThunk("settings/primaryColor", (primaryColor: string, thunkApi) => {
|
export const changePrimaryColor = createAppAsyncThunk("settings/primaryColor", (primaryColor: string, thunkApi) => {
|
||||||
const { settings } = thunkApi.getState().user
|
const { settings } = thunkApi.getState().user
|
||||||
if (!settings) return
|
if (!settings) return
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { useAppDispatch, useAppSelector } from "@/app/store"
|
|||||||
import type { IconDisplayMode, ScrollMode, SharingSettings } from "@/app/types"
|
import type { IconDisplayMode, ScrollMode, SharingSettings } from "@/app/types"
|
||||||
import {
|
import {
|
||||||
changeCustomContextMenu,
|
changeCustomContextMenu,
|
||||||
|
changeDisableMobileSwipe,
|
||||||
changeDisablePullToRefresh,
|
changeDisablePullToRefresh,
|
||||||
changeEntriesToKeepOnTopWhenScrolling,
|
changeEntriesToKeepOnTopWhenScrolling,
|
||||||
changeExternalLinkIconDisplayMode,
|
changeExternalLinkIconDisplayMode,
|
||||||
@@ -45,6 +46,7 @@ export function DisplaySettings() {
|
|||||||
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
|
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
|
||||||
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
|
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
|
||||||
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
|
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
|
||||||
|
const disableMobileSwipe = useAppSelector(state => state.user.settings?.disableMobileSwipe)
|
||||||
const infrequentThresholdDays = useAppSelector(state => state.user.settings?.infrequentThresholdDays)
|
const infrequentThresholdDays = useAppSelector(state => state.user.settings?.infrequentThresholdDays)
|
||||||
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
|
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
|
||||||
const primaryColor = useAppSelector(state => state.user.settings?.primaryColor) || Constants.theme.defaultPrimaryColor
|
const primaryColor = useAppSelector(state => state.user.settings?.primaryColor) || Constants.theme.defaultPrimaryColor
|
||||||
@@ -145,6 +147,12 @@ export function DisplaySettings() {
|
|||||||
onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))}
|
onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
label={<Trans>On mobile, disable swipe gesture to open the menu</Trans>}
|
||||||
|
checked={disableMobileSwipe}
|
||||||
|
onChange={async e => await dispatch(changeDisableMobileSwipe(e.currentTarget.checked))}
|
||||||
|
/>
|
||||||
|
|
||||||
<NumberInput
|
<NumberInput
|
||||||
label={<Trans>Infrequent posts threshold (days)</Trans>}
|
label={<Trans>Infrequent posts threshold (days)</Trans>}
|
||||||
description={<Trans>Feeds posting less often than this (on average) will appear in the Infrequent view</Trans>}
|
description={<Trans>Feeds posting less often than this (on average) will appear in the Infrequent view</Trans>}
|
||||||
|
|||||||
@@ -715,6 +715,10 @@ msgstr "On desktop"
|
|||||||
msgid "On mobile"
|
msgid "On mobile"
|
||||||
msgstr "On mobile"
|
msgstr "On mobile"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, disable swipe gesture to open the menu"
|
||||||
|
msgstr "On mobile, disable swipe gesture to open the menu"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
msgstr "On mobile, show action buttons at the bottom of the screen"
|
msgstr "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ export default function Layout(props: Readonly<LayoutProps>) {
|
|||||||
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
||||||
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
||||||
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
|
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
|
||||||
|
const disableMobileSwipe = useAppSelector(state => state.user.settings?.disableMobileSwipe)
|
||||||
const sidebarWidth = useAppSelector(state => state.user.localSettings.sidebarWidth)
|
const sidebarWidth = useAppSelector(state => state.user.localSettings.sidebarWidth)
|
||||||
const headerInFooter = mobile && !isBrowserExtensionPopup && mobileFooter
|
const headerInFooter = mobile && !isBrowserExtensionPopup && mobileFooter
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
@@ -164,6 +165,9 @@ export default function Layout(props: Readonly<LayoutProps>) {
|
|||||||
|
|
||||||
const swipeHandlers = useSwipeable({
|
const swipeHandlers = useSwipeable({
|
||||||
onSwiping: e => {
|
onSwiping: e => {
|
||||||
|
if (disableMobileSwipe) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const threshold = document.documentElement.clientWidth / 6
|
const threshold = document.documentElement.clientWidth / 6
|
||||||
if (e.absX > threshold) {
|
if (e.absX > threshold) {
|
||||||
dispatch(setMobileMenuOpen(e.dir === "Right"))
|
dispatch(setMobileMenuOpen(e.dir === "Right"))
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ public class UserSettings extends AbstractModel {
|
|||||||
private boolean unreadCountTitle;
|
private boolean unreadCountTitle;
|
||||||
private boolean unreadCountFavicon;
|
private boolean unreadCountFavicon;
|
||||||
private boolean disablePullToRefresh;
|
private boolean disablePullToRefresh;
|
||||||
|
private boolean disableMobileSwipe;
|
||||||
|
|
||||||
private int infrequentThresholdDays;
|
private int infrequentThresholdDays;
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ public class Settings implements Serializable {
|
|||||||
@Schema(description = "disable pull to refresh", required = true)
|
@Schema(description = "disable pull to refresh", required = true)
|
||||||
private boolean disablePullToRefresh;
|
private boolean disablePullToRefresh;
|
||||||
|
|
||||||
|
@Schema(description = "disable swipe gesture to open mobile menu", required = true)
|
||||||
|
private boolean disableMobileSwipe;
|
||||||
|
|
||||||
@Schema(description = "threshold in days for the infrequent view", required = true)
|
@Schema(description = "threshold in days for the infrequent view", required = true)
|
||||||
private int infrequentThresholdDays;
|
private int infrequentThresholdDays;
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ public class UserREST {
|
|||||||
s.setUnreadCountTitle(settings.isUnreadCountTitle());
|
s.setUnreadCountTitle(settings.isUnreadCountTitle());
|
||||||
s.setUnreadCountFavicon(settings.isUnreadCountFavicon());
|
s.setUnreadCountFavicon(settings.isUnreadCountFavicon());
|
||||||
s.setDisablePullToRefresh(settings.isDisablePullToRefresh());
|
s.setDisablePullToRefresh(settings.isDisablePullToRefresh());
|
||||||
|
s.setDisableMobileSwipe(settings.isDisableMobileSwipe());
|
||||||
s.setPrimaryColor(settings.getPrimaryColor());
|
s.setPrimaryColor(settings.getPrimaryColor());
|
||||||
s.setInfrequentThresholdDays(settings.getInfrequentThresholdDays());
|
s.setInfrequentThresholdDays(settings.getInfrequentThresholdDays());
|
||||||
|
|
||||||
@@ -169,6 +170,7 @@ public class UserREST {
|
|||||||
s.setUnreadCountTitle(false);
|
s.setUnreadCountTitle(false);
|
||||||
s.setUnreadCountFavicon(true);
|
s.setUnreadCountFavicon(true);
|
||||||
s.setDisablePullToRefresh(false);
|
s.setDisablePullToRefresh(false);
|
||||||
|
s.setDisableMobileSwipe(false);
|
||||||
s.setInfrequentThresholdDays(7);
|
s.setInfrequentThresholdDays(7);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
@@ -206,6 +208,7 @@ public class UserREST {
|
|||||||
s.setUnreadCountTitle(settings.isUnreadCountTitle());
|
s.setUnreadCountTitle(settings.isUnreadCountTitle());
|
||||||
s.setUnreadCountFavicon(settings.isUnreadCountFavicon());
|
s.setUnreadCountFavicon(settings.isUnreadCountFavicon());
|
||||||
s.setDisablePullToRefresh(settings.isDisablePullToRefresh());
|
s.setDisablePullToRefresh(settings.isDisablePullToRefresh());
|
||||||
|
s.setDisableMobileSwipe(settings.isDisableMobileSwipe());
|
||||||
s.setPrimaryColor(settings.getPrimaryColor());
|
s.setPrimaryColor(settings.getPrimaryColor());
|
||||||
s.setInfrequentThresholdDays(settings.getInfrequentThresholdDays());
|
s.setInfrequentThresholdDays(settings.getInfrequentThresholdDays());
|
||||||
|
|
||||||
|
|||||||
@@ -11,4 +11,12 @@
|
|||||||
</addColumn>
|
</addColumn>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet id="add-disable-mobile-swipe" author="athou">
|
||||||
|
<addColumn tableName="USERSETTINGS">
|
||||||
|
<column name="disableMobileSwipe" type="BOOLEAN" valueBoolean="false">
|
||||||
|
<constraints nullable="false" />
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
@@ -38,6 +38,6 @@
|
|||||||
<include file="changelogs/db.changelog-5.11.xml" />
|
<include file="changelogs/db.changelog-5.11.xml" />
|
||||||
<include file="changelogs/db.changelog-5.12.xml" />
|
<include file="changelogs/db.changelog-5.12.xml" />
|
||||||
<include file="changelogs/db.changelog-7.0.xml" />
|
<include file="changelogs/db.changelog-7.0.xml" />
|
||||||
<include file="changelogs/db.changelog-7.1.xml" />
|
<include file="changelogs/db.changelog-gmfork.xml" />
|
||||||
|
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
Reference in New Issue
Block a user