add option to keep some entries above the selected entry when scrolling

This commit is contained in:
Athou
2024-09-10 16:22:23 +02:00
parent ba496c1395
commit e119941762
46 changed files with 632 additions and 33 deletions

View File

@@ -62,6 +62,7 @@
"@types/tinycon": "^0.6.5", "@types/tinycon": "^0.6.5",
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.1",
"babel-plugin-macros": "^3.1.0", "babel-plugin-macros": "^3.1.0",
"jsdom": "^25.0.0",
"rollup-plugin-visualizer": "^5.12.0", "rollup-plugin-visualizer": "^5.12.0",
"typescript": "^5.6.2", "typescript": "^5.6.2",
"vite": "^5.4.3", "vite": "^5.4.3",
@@ -3292,12 +3293,71 @@
"url": "https://github.com/sponsors/fb55" "url": "https://github.com/sponsors/fb55"
} }
}, },
"node_modules/cssstyle": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz",
"integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==",
"dev": true,
"dependencies": {
"rrweb-cssom": "^0.7.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/data-urls": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
"integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
"dev": true,
"dependencies": {
"whatwg-mimetype": "^4.0.0",
"whatwg-url": "^14.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/data-urls/node_modules/tr46": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz",
"integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==",
"dev": true,
"dependencies": {
"punycode": "^2.3.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/data-urls/node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/data-urls/node_modules/whatwg-url": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz",
"integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==",
"dev": true,
"dependencies": {
"tr46": "^5.0.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/data-view-buffer": { "node_modules/data-view-buffer": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
@@ -3383,6 +3443,12 @@
} }
} }
}, },
"node_modules/decimal.js": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
"integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
"dev": true
},
"node_modules/decko": { "node_modules/decko": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz", "resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz",
@@ -3597,7 +3663,6 @@
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"peer": true,
"engines": { "engines": {
"node": ">=0.12" "node": ">=0.12"
}, },
@@ -4426,6 +4491,18 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/html-encoding-sniffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
"integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
"dev": true,
"dependencies": {
"whatwg-encoding": "^3.1.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/htmlparser2": { "node_modules/htmlparser2": {
"version": "9.1.0", "version": "9.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
@@ -4446,6 +4523,19 @@
"entities": "^4.5.0" "entities": "^4.5.0"
} }
}, },
"node_modules/http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
"dev": true,
"dependencies": {
"agent-base": "^7.1.0",
"debug": "^4.3.4"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/http2-client": { "node_modules/http2-client": {
"version": "1.3.5", "version": "1.3.5",
"resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz",
@@ -4909,6 +4999,12 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/is-potential-custom-element-name": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
"dev": true
},
"node_modules/is-regex": { "node_modules/is-regex": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -5194,6 +5290,80 @@
"js-yaml": "bin/js-yaml.js" "js-yaml": "bin/js-yaml.js"
} }
}, },
"node_modules/jsdom": {
"version": "25.0.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz",
"integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==",
"dev": true,
"dependencies": {
"cssstyle": "^4.0.1",
"data-urls": "^5.0.0",
"decimal.js": "^10.4.3",
"form-data": "^4.0.0",
"html-encoding-sniffer": "^4.0.0",
"http-proxy-agent": "^7.0.2",
"https-proxy-agent": "^7.0.5",
"is-potential-custom-element-name": "^1.0.1",
"nwsapi": "^2.2.12",
"parse5": "^7.1.2",
"rrweb-cssom": "^0.7.1",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^4.1.4",
"w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^7.0.0",
"whatwg-encoding": "^3.1.1",
"whatwg-mimetype": "^4.0.0",
"whatwg-url": "^14.0.0",
"ws": "^8.18.0",
"xml-name-validator": "^5.0.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"canvas": "^2.11.2"
},
"peerDependenciesMeta": {
"canvas": {
"optional": true
}
}
},
"node_modules/jsdom/node_modules/tr46": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz",
"integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==",
"dev": true,
"dependencies": {
"punycode": "^2.3.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/jsdom/node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/jsdom/node_modules/whatwg-url": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz",
"integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==",
"dev": true,
"dependencies": {
"tr46": "^5.0.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/jsesc": { "node_modules/jsesc": {
"version": "2.5.2", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -5782,6 +5952,12 @@
"url": "https://github.com/fb55/nth-check?sponsor=1" "url": "https://github.com/fb55/nth-check?sponsor=1"
} }
}, },
"node_modules/nwsapi": {
"version": "2.2.12",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz",
"integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==",
"dev": true
},
"node_modules/oas-kit-common": { "node_modules/oas-kit-common": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz",
@@ -6187,7 +6363,6 @@
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"entities": "^4.4.0" "entities": "^4.4.0"
}, },
@@ -6482,6 +6657,12 @@
"node": ">=16.0.0" "node": ">=16.0.0"
} }
}, },
"node_modules/psl": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
"dev": true
},
"node_modules/punycode": { "node_modules/punycode": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -6492,6 +6673,12 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
"dev": true
},
"node_modules/raf": { "node_modules/raf": {
"version": "3.4.1", "version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
@@ -7037,6 +7224,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true
},
"node_modules/reselect": { "node_modules/reselect": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
@@ -7166,6 +7359,12 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/rrweb-cssom": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
"integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
"dev": true
},
"node_modules/rst-selector-parser": { "node_modules/rst-selector-parser": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz",
@@ -7269,6 +7468,18 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/saxes": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
"integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
"dev": true,
"dependencies": {
"xmlchars": "^2.2.0"
},
"engines": {
"node": ">=v12.22.7"
}
},
"node_modules/scheduler": { "node_modules/scheduler": {
"version": "0.23.2", "version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
@@ -7693,6 +7904,12 @@
"url": "https://github.com/Mermade/oas-kit?sponsor=1" "url": "https://github.com/Mermade/oas-kit?sponsor=1"
} }
}, },
"node_modules/symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true
},
"node_modules/tabbable": { "node_modules/tabbable": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
@@ -7793,6 +8010,21 @@
"node": ">=8.0" "node": ">=8.0"
} }
}, },
"node_modules/tough-cookie": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
"dev": true,
"dependencies": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
"universalify": "^0.2.0",
"url-parse": "^1.5.3"
},
"engines": {
"node": ">=6"
}
},
"node_modules/tr46": { "node_modules/tr46": {
"version": "0.0.3", "version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -8019,6 +8251,15 @@
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/universalify": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
"dev": true,
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/unraw": { "node_modules/unraw": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz", "resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz",
@@ -8062,6 +8303,16 @@
"integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==", "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"dev": true,
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"node_modules/url-template": { "node_modules/url-template": {
"version": "2.0.8", "version": "2.0.8",
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
@@ -8809,6 +9060,18 @@
"vitest": ">=2.0.0" "vitest": ">=2.0.0"
} }
}, },
"node_modules/w3c-xmlserializer": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
"integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
"dev": true,
"dependencies": {
"xml-name-validator": "^5.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/wcwidth": { "node_modules/wcwidth": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
@@ -8836,7 +9099,6 @@
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
"integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"iconv-lite": "0.6.3" "iconv-lite": "0.6.3"
}, },
@@ -8849,7 +9111,6 @@
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0" "safer-buffer": ">= 2.1.2 < 3.0.0"
}, },
@@ -8862,7 +9123,6 @@
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
"integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=18" "node": ">=18"
} }
@@ -9002,6 +9262,42 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/ws": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"dev": true,
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xml-name-validator": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
"integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
"dev": true,
"engines": {
"node": ">=18"
}
},
"node_modules/xmlchars": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"dev": true
},
"node_modules/y18n": { "node_modules/y18n": {
"version": "5.0.8", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@@ -69,6 +69,7 @@
"@types/tinycon": "^0.6.5", "@types/tinycon": "^0.6.5",
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.1",
"babel-plugin-macros": "^3.1.0", "babel-plugin-macros": "^3.1.0",
"jsdom": "^25.0.0",
"rollup-plugin-visualizer": "^5.12.0", "rollup-plugin-visualizer": "^5.12.0",
"typescript": "^5.6.2", "typescript": "^5.6.2",
"vite": "^5.4.3", "vite": "^5.4.3",

View File

@@ -166,22 +166,34 @@ export const selectEntry = createAppAsyncThunk(
}) })
if (arg.scrollToEntry) { if (arg.scrollToEntry) {
const viewMode = state.user.localSettings.viewMode
const entryIndex = state.entries.entries.indexOf(entry)
const entriesToKeepOnTopWhenScrolling =
viewMode === "expanded" ? 0 : Math.min(state.user.settings?.entriesToKeepOnTopWhenScrolling ?? 0, entryIndex)
const entryToScrollTo = state.entries.entries[entryIndex - entriesToKeepOnTopWhenScrolling]
const entryElement = document.getElementById(Constants.dom.entryId(entry)) const entryElement = document.getElementById(Constants.dom.entryId(entry))
if (entryElement) { const entryElementToScrollTo = document.getElementById(Constants.dom.entryId(entryToScrollTo))
if (entryElement && entryElementToScrollTo) {
const scrollMode = state.user.settings?.scrollMode const scrollMode = state.user.settings?.scrollMode
const entryEntirelyVisible = Constants.layout.isTopVisible(entryElement) && Constants.layout.isBottomVisible(entryElement) const entryEntirelyVisible =
Constants.layout.isTopVisible(entryElementToScrollTo) && Constants.layout.isBottomVisible(entryElement)
if (scrollMode === "always" || (scrollMode === "if_needed" && !entryEntirelyVisible)) { if (scrollMode === "always" || (scrollMode === "if_needed" && !entryEntirelyVisible)) {
const scrollSpeed = state.user.settings?.scrollSpeed const scrollSpeed = state.user.settings?.scrollSpeed
const margin = viewMode === "detailed" ? 8 : 3
thunkApi.dispatch(entriesSlice.actions.setScrollingToEntry(true)) thunkApi.dispatch(entriesSlice.actions.setScrollingToEntry(true))
scrollToEntry(entryElement, scrollSpeed, () => thunkApi.dispatch(entriesSlice.actions.setScrollingToEntry(false))) scrollToEntry(entryElementToScrollTo, margin, scrollSpeed, () =>
thunkApi.dispatch(entriesSlice.actions.setScrollingToEntry(false))
)
} }
} }
} }
} }
) )
const scrollToEntry = (entryElement: HTMLElement, scrollSpeed: number | undefined, onScrollEnded: () => void) => { const scrollToEntry = (entryElement: HTMLElement, margin: number, scrollSpeed: number | undefined, onScrollEnded: () => void) => {
const header = document.getElementById(Constants.dom.headerId)?.getBoundingClientRect() const header = document.getElementById(Constants.dom.headerId)?.getBoundingClientRect()
const offset = (header?.bottom ?? 0) + 3 const offset = (header?.bottom ?? 0) + margin
scrollToWithCallback({ scrollToWithCallback({
options: { options: {
top: entryElement.offsetTop - offset, top: entryElement.offsetTop - offset,

View File

@@ -3,6 +3,7 @@ import { entriesSlice } from "app/entries/slice"
import { redirectSlice } from "app/redirect/slice" import { redirectSlice } from "app/redirect/slice"
import { serverSlice } from "app/server/slice" import { serverSlice } from "app/server/slice"
import { treeSlice } from "app/tree/slice" import { treeSlice } from "app/tree/slice"
import type { ViewMode } from "app/types"
import { userSlice } from "app/user/slice" import { userSlice } from "app/user/slice"
import { type TypedUseSelectorHook, useDispatch, useSelector } from "react-redux" import { type TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"
@@ -14,7 +15,20 @@ export const reducers = {
user: userSlice.reducer, user: userSlice.reducer,
} }
export const store = configureStore({ reducer: reducers }) export const store = configureStore({
reducer: reducers,
preloadedState: {
user: {
localSettings: {
viewMode: localStorage.getItem("view-mode") as ViewMode,
},
},
},
})
store.subscribe(() => {
const state = store.getState()
localStorage.setItem("view-mode", state.user.localSettings.viewMode)
})
export type RootState = ReturnType<typeof store.getState> export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch export type AppDispatch = typeof store.dispatch

View File

@@ -243,6 +243,7 @@ export interface Settings {
customJs?: string customJs?: string
scrollSpeed: number scrollSpeed: number
scrollMode: ScrollMode scrollMode: ScrollMode
entriesToKeepOnTopWhenScrolling: number
starIconDisplayMode: IconDisplayMode starIconDisplayMode: IconDisplayMode
externalLinkIconDisplayMode: IconDisplayMode externalLinkIconDisplayMode: IconDisplayMode
markAllAsReadConfirmation: boolean markAllAsReadConfirmation: boolean

View File

@@ -1,9 +1,10 @@
import { t } from "@lingui/macro" import { t } from "@lingui/macro"
import { showNotification } from "@mantine/notifications" import { showNotification } from "@mantine/notifications"
import { createSlice, isAnyOf } from "@reduxjs/toolkit" import { type PayloadAction, createSlice, isAnyOf } from "@reduxjs/toolkit"
import type { Settings, UserModel } from "app/types" import type { Settings, UserModel, ViewMode } from "app/types"
import { import {
changeCustomContextMenu, changeCustomContextMenu,
changeEntriesToKeepOnTopWhenScrolling,
changeExternalLinkIconDisplayMode, changeExternalLinkIconDisplayMode,
changeLanguage, changeLanguage,
changeMarkAllAsReadConfirmation, changeMarkAllAsReadConfirmation,
@@ -25,16 +26,27 @@ import {
interface UserState { interface UserState {
settings?: Settings settings?: Settings
localSettings: {
viewMode: ViewMode
}
profile?: UserModel profile?: UserModel
tags?: string[] tags?: string[]
} }
const initialState: UserState = {} const initialState: UserState = {
localSettings: {
viewMode: "detailed",
},
}
export const userSlice = createSlice({ export const userSlice = createSlice({
name: "user", name: "user",
initialState, initialState,
reducers: {}, reducers: {
setViewMode: (state, action: PayloadAction<ViewMode>) => {
state.localSettings.viewMode = action.payload
},
},
extraReducers: builder => { extraReducers: builder => {
builder.addCase(reloadSettings.fulfilled, (state, action) => { builder.addCase(reloadSettings.fulfilled, (state, action) => {
state.settings = action.payload state.settings = action.payload
@@ -73,6 +85,10 @@ export const userSlice = createSlice({
if (!state.settings) return if (!state.settings) return
state.settings.scrollMode = action.meta.arg state.settings.scrollMode = action.meta.arg
}) })
builder.addCase(changeEntriesToKeepOnTopWhenScrolling.pending, (state, action) => {
if (!state.settings) return
state.settings.entriesToKeepOnTopWhenScrolling = action.meta.arg
})
builder.addCase(changeStarIconDisplayMode.pending, (state, action) => { builder.addCase(changeStarIconDisplayMode.pending, (state, action) => {
if (!state.settings) return if (!state.settings) return
state.settings.starIconDisplayMode = action.meta.arg state.settings.starIconDisplayMode = action.meta.arg
@@ -112,6 +128,7 @@ export const userSlice = createSlice({
changeShowRead.fulfilled, changeShowRead.fulfilled,
changeScrollMarks.fulfilled, changeScrollMarks.fulfilled,
changeScrollMode.fulfilled, changeScrollMode.fulfilled,
changeEntriesToKeepOnTopWhenScrolling.fulfilled,
changeStarIconDisplayMode.fulfilled, changeStarIconDisplayMode.fulfilled,
changeExternalLinkIconDisplayMode.fulfilled, changeExternalLinkIconDisplayMode.fulfilled,
changeMarkAllAsReadConfirmation.fulfilled, changeMarkAllAsReadConfirmation.fulfilled,
@@ -130,3 +147,5 @@ export const userSlice = createSlice({
) )
}, },
}) })
export const { setViewMode } = userSlice.actions

View File

@@ -43,6 +43,14 @@ export const changeScrollMode = createAppAsyncThunk("settings/scrollMode", (scro
if (!settings) return if (!settings) return
client.user.saveSettings({ ...settings, scrollMode }) client.user.saveSettings({ ...settings, scrollMode })
}) })
export const changeEntriesToKeepOnTopWhenScrolling = createAppAsyncThunk(
"settings/entriesToKeepOnTopWhenScrolling",
(entriesToKeepOnTopWhenScrolling: number, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, entriesToKeepOnTopWhenScrolling })
}
)
export const changeStarIconDisplayMode = createAppAsyncThunk( export const changeStarIconDisplayMode = createAppAsyncThunk(
"settings/starIconDisplayMode", "settings/starIconDisplayMode",
(starIconDisplayMode: IconDisplayMode, thunkApi) => { (starIconDisplayMode: IconDisplayMode, thunkApi) => {

View File

@@ -20,7 +20,6 @@ import { KeyboardShortcutsHelp } from "components/KeyboardShortcutsHelp"
import { Loader } from "components/Loader" import { Loader } from "components/Loader"
import { useBrowserExtension } from "hooks/useBrowserExtension" import { useBrowserExtension } from "hooks/useBrowserExtension"
import { useMousetrap } from "hooks/useMousetrap" import { useMousetrap } from "hooks/useMousetrap"
import { useViewMode } from "hooks/useViewMode"
import { useEffect } from "react" import { useEffect } from "react"
import { useContextMenu } from "react-contexify" import { useContextMenu } from "react-contexify"
import InfiniteScroll from "react-infinite-scroller" import InfiniteScroll from "react-infinite-scroller"
@@ -38,7 +37,7 @@ export function FeedEntries() {
const scrollingToEntry = useAppSelector(state => state.entries.scrollingToEntry) const scrollingToEntry = useAppSelector(state => state.entries.scrollingToEntry)
const sidebarVisible = useAppSelector(state => state.tree.sidebarVisible) const sidebarVisible = useAppSelector(state => state.tree.sidebarVisible)
const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu) const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu)
const { viewMode } = useViewMode() const viewMode = useAppSelector(state => state.user.localSettings.viewMode)
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const { openLinkInBackgroundTab } = useBrowserExtension() const { openLinkInBackgroundTab } = useBrowserExtension()

View File

@@ -5,7 +5,6 @@ import type { Entry, ViewMode } from "app/types"
import { FeedEntryCompactHeader } from "components/content/header/FeedEntryCompactHeader" import { FeedEntryCompactHeader } from "components/content/header/FeedEntryCompactHeader"
import { FeedEntryHeader } from "components/content/header/FeedEntryHeader" import { FeedEntryHeader } from "components/content/header/FeedEntryHeader"
import { useMobile } from "hooks/useMobile" import { useMobile } from "hooks/useMobile"
import { useViewMode } from "hooks/useViewMode"
import type React from "react" import type React from "react"
import { useSwipeable } from "react-swipeable" import { useSwipeable } from "react-swipeable"
import { tss } from "tss" import { tss } from "tss"
@@ -95,7 +94,7 @@ const useStyles = tss
}) })
export function FeedEntry(props: FeedEntryProps) { export function FeedEntry(props: FeedEntryProps) {
const { viewMode } = useViewMode() const viewMode = useAppSelector(state => state.user.localSettings.viewMode)
const { classes, cx } = useStyles({ const { classes, cx } = useStyles({
read: props.entry.read, read: props.entry.read,
expanded: props.expanded, expanded: props.expanded,

View File

@@ -14,7 +14,7 @@ import { client } from "app/client"
import { redirectToAbout, redirectToAdminUsers, redirectToDonate, redirectToMetrics, redirectToSettings } from "app/redirect/thunks" import { redirectToAbout, redirectToAdminUsers, redirectToDonate, redirectToMetrics, redirectToSettings } from "app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "app/store" import { useAppDispatch, useAppSelector } from "app/store"
import type { ViewMode } from "app/types" import type { ViewMode } from "app/types"
import { useViewMode } from "hooks/useViewMode" import { setViewMode } from "app/user/slice"
import { type ReactNode, useState } from "react" import { type ReactNode, useState } from "react"
import { import {
TbChartLine, TbChartLine,
@@ -92,9 +92,9 @@ const viewModeData: ViewModeControlItem[] = [
export function ProfileMenu(props: ProfileMenuProps) { export function ProfileMenu(props: ProfileMenuProps) {
const [opened, setOpened] = useState(false) const [opened, setOpened] = useState(false)
const { viewMode, setViewMode } = useViewMode()
const profile = useAppSelector(state => state.user.profile) const profile = useAppSelector(state => state.user.profile)
const admin = useAppSelector(state => state.user.profile?.admin) const admin = useAppSelector(state => state.user.profile?.admin)
const viewMode = useAppSelector(state => state.user.localSettings.viewMode)
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const { colorScheme, setColorScheme } = useMantineColorScheme() const { colorScheme, setColorScheme } = useMantineColorScheme()
@@ -156,7 +156,7 @@ export function ProfileMenu(props: ProfileMenuProps) {
orientation="vertical" orientation="vertical"
data={viewModeData} data={viewModeData}
value={viewMode} value={viewMode}
onChange={e => setViewMode(e as ViewMode)} onChange={e => dispatch(setViewMode(e as ViewMode))}
mb="xs" mb="xs"
/> />

View File

@@ -1,12 +1,13 @@
import { Trans, msg } from "@lingui/macro" import { Trans, msg } from "@lingui/macro"
import { useLingui } from "@lingui/react" import { useLingui } from "@lingui/react"
import { Divider, Group, Radio, Select, SimpleGrid, Stack, Switch } from "@mantine/core" import { Divider, Group, NumberInput, Radio, Select, SimpleGrid, Stack, Switch } from "@mantine/core"
import type { ComboboxData } from "@mantine/core/lib/components/Combobox/Combobox.types" import type { ComboboxData } from "@mantine/core/lib/components/Combobox/Combobox.types"
import { Constants } from "app/constants" import { Constants } from "app/constants"
import { useAppDispatch, useAppSelector } from "app/store" 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,
changeEntriesToKeepOnTopWhenScrolling,
changeExternalLinkIconDisplayMode, changeExternalLinkIconDisplayMode,
changeLanguage, changeLanguage,
changeMarkAllAsReadConfirmation, changeMarkAllAsReadConfirmation,
@@ -29,6 +30,7 @@ export function DisplaySettings() {
const showRead = useAppSelector(state => state.user.settings?.showRead) const showRead = useAppSelector(state => state.user.settings?.showRead)
const scrollMarks = useAppSelector(state => state.user.settings?.scrollMarks) const scrollMarks = useAppSelector(state => state.user.settings?.scrollMarks)
const scrollMode = useAppSelector(state => state.user.settings?.scrollMode) const scrollMode = useAppSelector(state => state.user.settings?.scrollMode)
const entriesToKeepOnTop = useAppSelector(state => state.user.settings?.entriesToKeepOnTopWhenScrolling)
const starIconDisplayMode = useAppSelector(state => state.user.settings?.starIconDisplayMode) const starIconDisplayMode = useAppSelector(state => state.user.settings?.starIconDisplayMode)
const externalLinkIconDisplayMode = useAppSelector(state => state.user.settings?.externalLinkIconDisplayMode) const externalLinkIconDisplayMode = useAppSelector(state => state.user.settings?.externalLinkIconDisplayMode)
const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation) const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation)
@@ -145,6 +147,14 @@ export function DisplaySettings() {
</Group> </Group>
</Radio.Group> </Radio.Group>
<NumberInput
label={<Trans>Entries to keep above the selected entry when scrolling</Trans>}
description={<Trans>Only applies to compact, cozy and detailed modes</Trans>}
min={0}
value={entriesToKeepOnTop}
onChange={async value => await dispatch(changeEntriesToKeepOnTopWhenScrolling(+value))}
/>
<Switch <Switch
label={<Trans>Scroll smoothly when navigating between entries</Trans>} label={<Trans>Scroll smoothly when navigating between entries</Trans>}
checked={scrollSpeed ? scrollSpeed > 0 : false} checked={scrollSpeed ? scrollSpeed > 0 : false}

View File

@@ -1,7 +0,0 @@
import type { ViewMode } from "app/types"
import useLocalStorage from "use-local-storage"
export function useViewMode() {
const [viewMode, setViewMode] = useLocalStorage<ViewMode>("view-mode", "detailed")
return { viewMode, setViewMode }
}

View File

@@ -321,6 +321,10 @@ msgstr "دخول"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "أدخل كلمة المرور الحالية لتغيير إعدادات ملف التعريف" msgstr "أدخل كلمة المرور الحالية لتغيير إعدادات ملف التعريف"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "اوووه!" msgstr "اوووه!"

View File

@@ -321,6 +321,10 @@ msgstr "Entra"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "introduïu la vostra contrasenya actual per canviar la configuració del perfil" msgstr "introduïu la vostra contrasenya actual per canviar la configuració del perfil"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "Al mòbil, mostra els botons d'acció a la part inferior de la pantalla" msgstr "Al mòbil, mostra els botons d'acció a la part inferior de la pantalla"
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Vaja!" msgstr "Vaja!"

View File

@@ -321,6 +321,10 @@ msgstr "Vstupte"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Zadejte své aktuální heslo pro změnu nastavení profilu" msgstr "Zadejte své aktuální heslo pro změnu nastavení profilu"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Jejda!" msgstr "Jejda!"

View File

@@ -321,6 +321,10 @@ msgstr "Ewch i mewn"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Rhowch eich cyfrinair presennol i newid gosodiadau proffil" msgstr "Rhowch eich cyfrinair presennol i newid gosodiadau proffil"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Wps!" msgstr "Wps!"

View File

@@ -321,6 +321,10 @@ msgstr ""
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Indtast din nuværende adgangskode for at ændre profilindstillinger" msgstr "Indtast din nuværende adgangskode for at ændre profilindstillinger"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Hovsa!" msgstr "Hovsa!"

View File

@@ -321,6 +321,10 @@ msgstr "Eintreten"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Geben Sie Ihr aktuelles Passwort ein, um die Profileinstellungen zu ändern" msgstr "Geben Sie Ihr aktuelles Passwort ein, um die Profileinstellungen zu ändern"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "Auf mobilen Geräten die Aktion-Buttons am unteren Ende des Bildschirms anzeigen" msgstr "Auf mobilen Geräten die Aktion-Buttons am unteren Ende des Bildschirms anzeigen"
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Ups!" msgstr "Ups!"

View File

@@ -321,6 +321,10 @@ msgstr "Enter"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Enter your current password to change profile settings" msgstr "Enter your current password to change profile settings"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr "Entries to keep above the selected entry when scrolling"
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "Entry headers" msgstr "Entry headers"
@@ -608,6 +612,10 @@ msgstr "On mobile"
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"
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr "Only applies to compact, cozy and detailed modes"
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Oops!" msgstr "Oops!"

View File

@@ -321,6 +321,10 @@ msgstr "Entrar"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Ingrese su contraseña actual para cambiar la configuración del perfil" msgstr "Ingrese su contraseña actual para cambiar la configuración del perfil"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "¡Ups!" msgstr "¡Ups!"

View File

@@ -321,6 +321,10 @@ msgstr "وارد شوید"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "رمز عبور فعلی خود را برای تغییر تنظیمات نمایه وارد کنید" msgstr "رمز عبور فعلی خود را برای تغییر تنظیمات نمایه وارد کنید"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "اوه!" msgstr "اوه!"

View File

@@ -321,6 +321,10 @@ msgstr ""
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Anna nykyinen salasanasi muuttaaksesi profiiliasetuksia" msgstr "Anna nykyinen salasanasi muuttaaksesi profiiliasetuksia"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Hups!" msgstr "Hups!"

View File

@@ -321,6 +321,10 @@ msgstr "Entrer"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Entrez votre mot de passe actuel pour changer les paramètres du profil" msgstr "Entrez votre mot de passe actuel pour changer les paramètres du profil"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "En-têtes de l'entrée" msgstr "En-têtes de l'entrée"
@@ -608,6 +612,10 @@ msgstr "Version mobile"
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 "Sur mobile, afficher les boutons d'action en bas de l'écran" msgstr "Sur mobile, afficher les boutons d'action en bas de l'écran"
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Oups !" msgstr "Oups !"

View File

@@ -321,6 +321,10 @@ msgstr "Entra"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Introduce o teu contrasinal actual para cambiar a configuración do perfil" msgstr "Introduce o teu contrasinal actual para cambiar a configuración do perfil"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Vaia!" msgstr "Vaia!"

View File

@@ -321,6 +321,10 @@ msgstr ""
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Adja meg jelenlegi jelszavát a profilbeállítások módosításához" msgstr "Adja meg jelenlegi jelszavát a profilbeállítások módosításához"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Hoppá!" msgstr "Hoppá!"

View File

@@ -321,6 +321,10 @@ msgstr "Masuk"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Masukkan kata sandi Anda saat ini untuk mengubah pengaturan profil" msgstr "Masukkan kata sandi Anda saat ini untuk mengubah pengaturan profil"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Ups!" msgstr "Ups!"

View File

@@ -321,6 +321,10 @@ msgstr "Invio"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Inserisci la tua password attuale per modificare le impostazioni del profilo" msgstr "Inserisci la tua password attuale per modificare le impostazioni del profilo"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Ops!" msgstr "Ops!"

View File

@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n" "PO-Revision-Date: \n"
"Last-Translator: https://github.com/dai \n" "Last-Translator: https://github.com/dai\n"
"Language-Team: \n" "Language-Team: \n"
"Plural-Forms: \n" "Plural-Forms: \n"
@@ -29,7 +29,6 @@ msgstr "<0>アカウントをお持ちですか?</0><1>ログインしてくだ
msgid "<0>Hey,</0><1>I'm Jérémie from Belgium and I've been working on CommaFeed in my free time for over 10 years now. Thanks for taking an interest in helping me continue supporting CommaFeed.</1>" msgid "<0>Hey,</0><1>I'm Jérémie from Belgium and I've been working on CommaFeed in my free time for over 10 years now. Thanks for taking an interest in helping me continue supporting CommaFeed.</1>"
msgstr "<0>こんにちは、</0><1>私はベルギーのジェレミーです。私はこれまで 10 年以上、CommaFeed のオープンソースプロジェクトを無料で開発してきました。あなたの関心に感謝します。</1>" msgstr "<0>こんにちは、</0><1>私はベルギーのジェレミーです。私はこれまで 10 年以上、CommaFeed のオープンソースプロジェクトを無料で開発してきました。あなたの関心に感謝します。</1>"
#: src/pages/auth/LoginPage.tsx #: src/pages/auth/LoginPage.tsx
msgid "<0>Need an account?</0><1>Sign up!</1>" msgid "<0>Need an account?</0><1>Sign up!</1>"
msgstr "<0>アカウントが必要ですか?</0><1>サインアップ!</1>" msgstr "<0>アカウントが必要ですか?</0><1>サインアップ!</1>"
@@ -322,6 +321,10 @@ msgstr "入力"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "プロファイル設定を変更するには、現在のパスワードを入力してください" msgstr "プロファイル設定を変更するには、現在のパスワードを入力してください"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "エントリーヘッダー" msgstr "エントリーヘッダー"
@@ -609,6 +612,10 @@ msgstr "モバイル"
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 "モバイルでは、画面の下部にアクションボタンを表示します" msgstr "モバイルでは、画面の下部にアクションボタンを表示します"
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "おっと!" msgstr "おっと!"
@@ -799,7 +806,6 @@ msgstr "Shift"
msgid "Show CommaFeed's own context menu on right click" msgid "Show CommaFeed's own context menu on right click"
msgstr "右クリックでCommaFeedのコンテキストメニューを表示する" msgstr "右クリックでCommaFeedのコンテキストメニューを表示する"
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Show confirmation when marking all entries as read" msgid "Show confirmation when marking all entries as read"
msgstr "すべてのエントリーを既読にするときに確認を表示する" msgstr "すべてのエントリーを既読にするときに確認を表示する"

View File

@@ -321,6 +321,10 @@ msgstr "입력"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "프로필 설정을 변경하려면 현재 비밀번호를 입력하세요." msgstr "프로필 설정을 변경하려면 현재 비밀번호를 입력하세요."
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "앗!" msgstr "앗!"

View File

@@ -321,6 +321,10 @@ msgstr "Masuk"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Masukkan kata laluan semasa anda untuk menukar tetapan profil" msgstr "Masukkan kata laluan semasa anda untuk menukar tetapan profil"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Aduh!" msgstr "Aduh!"

View File

@@ -321,6 +321,10 @@ msgstr ""
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Skriv inn ditt nåværende passord for å endre profilinnstillinger" msgstr "Skriv inn ditt nåværende passord for å endre profilinnstillinger"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Beklager!" msgstr "Beklager!"

View File

@@ -321,6 +321,10 @@ msgstr ""
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Voer uw huidige wachtwoord in om de profielinstellingen te wijzigen" msgstr "Voer uw huidige wachtwoord in om de profielinstellingen te wijzigen"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Oeps!" msgstr "Oeps!"

View File

@@ -321,6 +321,10 @@ msgstr ""
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Skriv inn ditt nåværende passord for å endre profilinnstillinger" msgstr "Skriv inn ditt nåværende passord for å endre profilinnstillinger"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Beklager!" msgstr "Beklager!"

View File

@@ -321,6 +321,10 @@ msgstr "Wprowadź"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Wprowadź swoje aktualne hasło, aby zmienić ustawienia profilu" msgstr "Wprowadź swoje aktualne hasło, aby zmienić ustawienia profilu"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Ups!" msgstr "Ups!"

View File

@@ -321,6 +321,10 @@ msgstr "Entrar"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Digite sua senha atual para alterar as configurações do perfil" msgstr "Digite sua senha atual para alterar as configurações do perfil"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Opa!" msgstr "Opa!"

View File

@@ -321,6 +321,10 @@ msgstr "Ввод"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Введите текущий пароль, чтобы изменить настройки профиля." msgstr "Введите текущий пароль, чтобы изменить настройки профиля."
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "На мобильных устройствах отображать кнопки действий в нижней части экрана" msgstr "На мобильных устройствах отображать кнопки действий в нижней части экрана"
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Ой!" msgstr "Ой!"

View File

@@ -321,6 +321,10 @@ msgstr "Vstúpte"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Ak chcete zmeniť nastavenia profilu, zadajte svoje aktuálne heslo" msgstr "Ak chcete zmeniť nastavenia profilu, zadajte svoje aktuálne heslo"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Ojoj!" msgstr "Ojoj!"

View File

@@ -321,6 +321,10 @@ msgstr ""
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Ange ditt nuvarande lösenord för att ändra profilinställningar" msgstr "Ange ditt nuvarande lösenord för att ändra profilinställningar"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Hoppsan!" msgstr "Hoppsan!"

View File

@@ -321,6 +321,10 @@ msgstr "Girin"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "Profil ayarlarını değiştirmek için mevcut şifrenizi girin" msgstr "Profil ayarlarını değiştirmek için mevcut şifrenizi girin"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "" msgstr ""
@@ -608,6 +612,10 @@ msgstr ""
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 "" msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "Hata!" msgstr "Hata!"

View File

@@ -321,6 +321,10 @@ msgstr "回车"
msgid "Enter your current password to change profile settings" msgid "Enter your current password to change profile settings"
msgstr "输入您当前的密码以更改配置文件设置" msgstr "输入您当前的密码以更改配置文件设置"
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
#: src/components/settings/DisplaySettings.tsx #: src/components/settings/DisplaySettings.tsx
msgid "Entry headers" msgid "Entry headers"
msgstr "条目头部" msgstr "条目头部"
@@ -608,6 +612,10 @@ msgstr "移动端"
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 "在移动端,显示屏幕底部的操作按钮" msgstr "在移动端,显示屏幕底部的操作按钮"
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
#: src/pages/ErrorPage.tsx #: src/pages/ErrorPage.tsx
msgid "Oops!" msgid "Oops!"
msgstr "哎呀!" msgstr "哎呀!"

View File

@@ -49,4 +49,7 @@ export default defineConfig(env => ({
}, },
}, },
}, },
test: {
environment: "jsdom",
},
})) }))

View File

@@ -78,6 +78,8 @@ public class UserSettings extends AbstractModel {
@Column(nullable = false) @Column(nullable = false)
private ScrollMode scrollMode; private ScrollMode scrollMode;
private int entriesToKeepOnTopWhenScrolling;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(nullable = false) @Column(nullable = false)
private IconDisplayMode starIconDisplayMode; private IconDisplayMode starIconDisplayMode;

View File

@@ -49,6 +49,9 @@ public class Settings implements Serializable {
requiredMode = RequiredMode.REQUIRED) requiredMode = RequiredMode.REQUIRED)
private String scrollMode; private String scrollMode;
@Schema(description = "number of entries to keep above the selected entry when scrolling", requiredMode = RequiredMode.REQUIRED)
private int entriesToKeepOnTopWhenScrolling;
@Schema( @Schema(
description = "whether to show the star icon in the header of entries", description = "whether to show the star icon in the header of entries",
allowableValues = "always,never,on_desktop,on_mobile", allowableValues = "always,never,on_desktop,on_mobile",

View File

@@ -114,6 +114,7 @@ public class UserREST {
s.setLanguage(settings.getLanguage()); s.setLanguage(settings.getLanguage());
s.setScrollSpeed(settings.getScrollSpeed()); s.setScrollSpeed(settings.getScrollSpeed());
s.setScrollMode(settings.getScrollMode().name()); s.setScrollMode(settings.getScrollMode().name());
s.setEntriesToKeepOnTopWhenScrolling(settings.getEntriesToKeepOnTopWhenScrolling());
s.setStarIconDisplayMode(settings.getStarIconDisplayMode().name()); s.setStarIconDisplayMode(settings.getStarIconDisplayMode().name());
s.setExternalLinkIconDisplayMode(settings.getExternalLinkIconDisplayMode().name()); s.setExternalLinkIconDisplayMode(settings.getExternalLinkIconDisplayMode().name());
s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation()); s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation());
@@ -139,6 +140,7 @@ public class UserREST {
s.setLanguage("en"); s.setLanguage("en");
s.setScrollSpeed(400); s.setScrollSpeed(400);
s.setScrollMode(ScrollMode.if_needed.name()); s.setScrollMode(ScrollMode.if_needed.name());
s.setEntriesToKeepOnTopWhenScrolling(0);
s.setStarIconDisplayMode(IconDisplayMode.on_desktop.name()); s.setStarIconDisplayMode(IconDisplayMode.on_desktop.name());
s.setExternalLinkIconDisplayMode(IconDisplayMode.on_desktop.name()); s.setExternalLinkIconDisplayMode(IconDisplayMode.on_desktop.name());
s.setMarkAllAsReadConfirmation(true); s.setMarkAllAsReadConfirmation(true);
@@ -172,6 +174,7 @@ public class UserREST {
s.setLanguage(settings.getLanguage()); s.setLanguage(settings.getLanguage());
s.setScrollSpeed(settings.getScrollSpeed()); s.setScrollSpeed(settings.getScrollSpeed());
s.setScrollMode(ScrollMode.valueOf(settings.getScrollMode())); s.setScrollMode(ScrollMode.valueOf(settings.getScrollMode()));
s.setEntriesToKeepOnTopWhenScrolling(settings.getEntriesToKeepOnTopWhenScrolling());
s.setStarIconDisplayMode(IconDisplayMode.valueOf(settings.getStarIconDisplayMode())); s.setStarIconDisplayMode(IconDisplayMode.valueOf(settings.getStarIconDisplayMode()));
s.setExternalLinkIconDisplayMode(IconDisplayMode.valueOf(settings.getExternalLinkIconDisplayMode())); s.setExternalLinkIconDisplayMode(IconDisplayMode.valueOf(settings.getExternalLinkIconDisplayMode()));
s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation()); s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation());

View File

@@ -0,0 +1,13 @@
<?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="entriesToKeepOnTopWhenScrolling-setting" author="athou">
<addColumn tableName="USERSETTINGS">
<column name="entriesToKeepOnTopWhenScrolling" type="INT" valueNumeric="0">
<constraints nullable="false" />
</column>
</addColumn>
</changeSet>
</databaseChangeLog>

View File

@@ -32,5 +32,6 @@
<include file="changelogs/db.changelog-4.3.xml" /> <include file="changelogs/db.changelog-4.3.xml" />
<include file="changelogs/db.changelog-4.4.xml" /> <include file="changelogs/db.changelog-4.4.xml" />
<include file="changelogs/db.changelog-5.1.xml" /> <include file="changelogs/db.changelog-5.1.xml" />
<include file="changelogs/db.changelog-5.2.xml" />
</databaseChangeLog> </databaseChangeLog>