make "disable pull to refresh" a setting (#1168)

This commit is contained in:
Athou
2025-11-17 08:47:54 +01:00
parent 9c058cf6d6
commit ae78e4691d
42 changed files with 163 additions and 58 deletions

View File

@@ -29,7 +29,6 @@
"react": "^19.2.0",
"react-async-hook": "^4.0.0",
"react-contexify": "^6.0.0",
"react-device-detect": "^2.2.3",
"react-dom": "^19.2.0",
"react-draggable": "^4.5.0",
"react-icons": "^5.5.0",
@@ -5058,19 +5057,6 @@
"node": ">=6"
}
},
"node_modules/react-device-detect": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/react-device-detect/-/react-device-detect-2.2.3.tgz",
"integrity": "sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==",
"license": "MIT",
"dependencies": {
"ua-parser-js": "^1.0.33"
},
"peerDependencies": {
"react": ">= 0.14.0",
"react-dom": ">= 0.14.0"
}
},
"node_modules/react-dom": {
"version": "19.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
@@ -6131,32 +6117,6 @@
"node": ">=14.17"
}
},
"node_modules/ua-parser-js": {
"version": "1.0.41",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz",
"integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/ua-parser-js"
},
{
"type": "paypal",
"url": "https://paypal.me/faisalman"
},
{
"type": "github",
"url": "https://github.com/sponsors/faisalman"
}
],
"license": "MIT",
"bin": {
"ua-parser-js": "script/cli.js"
},
"engines": {
"node": "*"
}
},
"node_modules/undici-types": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",

View File

@@ -36,7 +36,6 @@
"react": "^19.2.0",
"react-async-hook": "^4.0.0",
"react-contexify": "^6.0.0",
"react-device-detect": "^2.2.3",
"react-dom": "^19.2.0",
"react-draggable": "^4.5.0",
"react-icons": "^5.5.0",

View File

@@ -5,7 +5,6 @@ import { ModalsProvider } from "@mantine/modals"
import { Notifications } from "@mantine/notifications"
import type React from "react"
import { useEffect, useState } from "react"
import { isSafari } from "react-device-detect"
import { HashRouter, Navigate, Route, Routes, useNavigate } from "react-router-dom"
import Tinycon from "tinycon"
import { Constants } from "@/app/constants"
@@ -200,6 +199,7 @@ export function App() {
useI18n()
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
const dispatch = useAppDispatch()
useEffect(() => {
@@ -213,12 +213,7 @@ export function App() {
<BrowserExtensionBadgeUnreadCountHandler />
<CustomJsHandler />
<CustomCssHandler />
{/* disable pull-to-refresh as it messes with vertical scrolling
safari behaves weirdly when overscroll-behavior is set to none so we disable it only for other browsers
https://github.com/Athou/commafeed/issues/1168
*/}
{!isSafari && <DisablePullToRefresh />}
<DisablePullToRefresh enabled={disablePullToRefresh} />
<HashRouter>
<RedirectHandler />

View File

@@ -252,6 +252,7 @@ export interface Settings {
mobileFooter: boolean
unreadCountTitle: boolean
unreadCountFavicon: boolean
disablePullToRefresh: boolean
primaryColor?: string
sharingSettings: SharingSettings
}

View File

@@ -4,6 +4,7 @@ import { createSlice, isAnyOf, type PayloadAction } from "@reduxjs/toolkit"
import type { LocalSettings, Settings, UserModel, ViewMode } from "@/app/types"
import {
changeCustomContextMenu,
changeDisablePullToRefresh,
changeEntriesToKeepOnTopWhenScrolling,
changeExternalLinkIconDisplayMode,
changeLanguage,
@@ -135,6 +136,10 @@ export const userSlice = createSlice({
if (!state.settings) return
state.settings.unreadCountFavicon = action.meta.arg
})
builder.addCase(changeDisablePullToRefresh.pending, (state, action) => {
if (!state.settings) return
state.settings.disablePullToRefresh = action.meta.arg
})
builder.addCase(changePrimaryColor.pending, (state, action) => {
if (!state.settings) return
state.settings.primaryColor = action.meta.arg
@@ -143,6 +148,7 @@ export const userSlice = createSlice({
if (!state.settings) return
state.settings.sharingSettings[action.meta.arg.site] = action.meta.arg.value
})
builder.addMatcher(
isAnyOf(
changeLanguage.fulfilled,
@@ -159,6 +165,7 @@ export const userSlice = createSlice({
changeMobileFooter.fulfilled,
changeUnreadCountTitle.fulfilled,
changeUnreadCountFavicon.fulfilled,
changeDisablePullToRefresh.fulfilled,
changePrimaryColor.fulfilled,
changeSharingSetting.fulfilled
),

View File

@@ -122,6 +122,15 @@ export const changeUnreadCountFavicon = createAppAsyncThunk("settings/unreadCoun
client.user.saveSettings({ ...settings, unreadCountFavicon })
})
export const changeDisablePullToRefresh = createAppAsyncThunk(
"settings/disablePullToRefresh",
(disablePullToRefresh: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, disablePullToRefresh })
}
)
export const changePrimaryColor = createAppAsyncThunk("settings/primaryColor", (primaryColor: string, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return

View File

@@ -1,4 +0,0 @@
html,
body {
overscroll-behavior: none;
}

View File

@@ -1,4 +1,3 @@
export const DisablePullToRefresh = () => {
import("./DisablePullToRefresh.css")
return null
export const DisablePullToRefresh = ({ enabled }: { enabled: boolean | undefined }) => {
return enabled ? <style>{`html, body { overscroll-behavior: none; }`}</style> : null
}

View File

@@ -9,6 +9,7 @@ import { useAppDispatch, useAppSelector } from "@/app/store"
import type { IconDisplayMode, ScrollMode, SharingSettings } from "@/app/types"
import {
changeCustomContextMenu,
changeDisablePullToRefresh,
changeEntriesToKeepOnTopWhenScrolling,
changeExternalLinkIconDisplayMode,
changeLanguage,
@@ -42,6 +43,7 @@ export function DisplaySettings() {
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
const primaryColor = useAppSelector(state => state.user.settings?.primaryColor) || Constants.theme.defaultPrimaryColor
const { _ } = useLingui()
@@ -211,6 +213,12 @@ export function DisplaySettings() {
onChange={async e => await dispatch(changeScrollMarks(e.currentTarget.checked))}
/>
<Switch
label={<Trans>Disable "Pull to refresh" browser behavior</Trans>}
checked={disablePullToRefresh}
onChange={async e => await dispatch(changeDisablePullToRefresh(e.currentTarget.checked))}
/>
<Divider label={<Trans>Sharing sites</Trans>} labelPosition="center" />
<SimpleGrid cols={2}>

View File

@@ -283,6 +283,10 @@ msgstr "تنازلي"
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Desc"
msgid "Detailed"
msgstr "Detallat"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Rhag"
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Beschr"
msgid "Detailed"
msgstr "Detailliert"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Desc"
msgid "Detailed"
msgstr "Detailed"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr "Disable \"Pull to refresh\" browser behavior"
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -284,6 +284,10 @@ msgstr "Desc"
msgid "Detailed"
msgstr "Detallado"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "توصیف"
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Descendant"
msgid "Detailed"
msgstr "Vue détaillée"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -284,6 +284,10 @@ msgstr "Desc"
msgid "Detailed"
msgstr "Detallado"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx
@@ -326,7 +330,6 @@ msgid "Enabled"
msgstr "Activado"
#: src/components/KeyboardShortcutsHelp.tsx
#, fuzzy
msgid "Enter"
msgstr "Entra"
@@ -431,7 +434,6 @@ msgid "Go to the API documentation."
msgstr "Ir á documentación da API."
#: src/pages/app/AboutPage.tsx
#, fuzzy
msgid "Goodies"
msgstr "Agasallos"
@@ -632,7 +634,6 @@ msgid "Next refresh"
msgstr "Próxima actualización"
#: src/pages/app/AboutPage.tsx
#, fuzzy
msgid "Next unread item bookmarklet"
msgstr "Seguinte marcador de elementos non lidos"

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "説明"
msgid "Detailed"
msgstr "詳細"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "설명"
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Dec"
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Beschrijving"
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Opis"
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Desc"
msgid "Detailed"
msgstr "Detalhado"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "По убыванию"
msgid "Detailed"
msgstr "Подробно"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr ""
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "Açılış"
msgid "Detailed"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -283,6 +283,10 @@ msgstr "降序"
msgid "Detailed"
msgstr "详细"
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr ""
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx

View File

@@ -131,6 +131,7 @@ public class UserSettings extends AbstractModel {
private boolean mobileFooter;
private boolean unreadCountTitle;
private boolean unreadCountFavicon;
private boolean disablePullToRefresh;
private boolean email;
private boolean gmail;

View File

@@ -72,6 +72,9 @@ public class Settings implements Serializable {
@Schema(description = "show unread count in the favicon", required = true)
private boolean unreadCountFavicon;
@Schema(description = "disable pull to refresh", required = true)
private boolean disablePullToRefresh;
@Schema(description = "primary theme color to use in the UI")
private String primaryColor;

View File

@@ -120,6 +120,7 @@ public class UserREST {
s.setMobileFooter(settings.isMobileFooter());
s.setUnreadCountTitle(settings.isUnreadCountTitle());
s.setUnreadCountFavicon(settings.isUnreadCountFavicon());
s.setDisablePullToRefresh(settings.isDisablePullToRefresh());
s.setPrimaryColor(settings.getPrimaryColor());
} else {
s.setReadingMode(ReadingMode.UNREAD);
@@ -148,6 +149,7 @@ public class UserREST {
s.setMobileFooter(false);
s.setUnreadCountTitle(false);
s.setUnreadCountFavicon(true);
s.setDisablePullToRefresh(true);
}
return s;
}
@@ -183,6 +185,7 @@ public class UserREST {
s.setMobileFooter(settings.isMobileFooter());
s.setUnreadCountTitle(settings.isUnreadCountTitle());
s.setUnreadCountFavicon(settings.isUnreadCountFavicon());
s.setDisablePullToRefresh(settings.isDisablePullToRefresh());
s.setPrimaryColor(settings.getPrimaryColor());
s.setEmail(settings.getSharingSettings().isEmail());

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="add-disablePullToRefresh-setting" author="athou">
<addColumn tableName="USERSETTINGS">
<column name="disablePullToRefresh" type="BOOLEAN" valueBoolean="false">
<constraints nullable="false" />
</column>
</addColumn>
</changeSet>
</databaseChangeLog>

View File

@@ -36,5 +36,6 @@
<include file="changelogs/db.changelog-5.3.xml" />
<include file="changelogs/db.changelog-5.8.xml" />
<include file="changelogs/db.changelog-5.11.xml" />
<include file="changelogs/db.changelog-5.12.xml" />
</databaseChangeLog>