diff --git a/src/routes/Settings/SectionsList/SectionsList.js b/src/routes/Settings/SectionsList/SectionsList.js
new file mode 100644
index 000000000..201ca4138
--- /dev/null
+++ b/src/routes/Settings/SectionsList/SectionsList.js
@@ -0,0 +1,103 @@
+const React = require('react');
+const { Button, Dropdown, Checkbox, ColorInput } = require('stremio/common');
+const Icon = require('stremio-icons/dom/Icon');
+const classnames = require('classnames');
+const styles = require('../styles');
+
+const SectionsList = React.forwardRef(({className, sections, preferences, onPreferenceChanged, onScroll }, ref) => {
+ const scrollContainerRef = ref;
+ const toggleCheckbox = (id) => {
+ onPreferenceChanged(id, !preferences[id]);
+ };
+
+ const colorChanged = (id, color) => {
+ onPreferenceChanged(id, color);
+ };
+
+ const updateDropdown = (event) => {
+ var data = event.currentTarget.dataset;
+ onPreferenceChanged(data.name, data.value);
+ };
+
+ return (
+
+ {sections.map((section) =>
+
+
{section.id}
+ {(section.inputs || [])
+ .map((input) => {
+ if (input.type === 'user') {
+ return (
+
+ {
+ !preferences[input.id]
+ ?
+
+ :
+
+ }
+
{!preferences[input.id] ? 'Anonymous user' : preferences[input.id].email}
+
+ );
+ } else if (input.type === 'select') {
+ return (
+
+ {input.header ?
{input.header}
: null}
+
+
+ );
+ } else if (input.type === 'link') {
+ return (
+
+ {input.header ?
{input.header}
: null}
+
+ {input.label}
+
+
+ );
+ } else if (input.type === 'button') {
+ return (
+
+ {input.header ?
{input.header}
: null}
+
+ {input.icon ? : null}
+ {input.label}
+
+
+ );
+ } else if (input.type === 'checkbox') {
+ return (
+
+ {input.header ?
{input.header}
: null}
+
+ {input.label}
+
+
+ );
+ } else if (input.type === 'static-text') {
+ return (
+
+ {input.header ?
{input.header}
: null}
+
+ {input.icon ?
: null}
+
{input.label}
+
+
+ );
+ } else if (input.type === 'color') {
+ return (
+
+ {input.header ?
{input.header}
: null}
+
+ {/*
*/}
+
+ );
+ }
+ })}
+
+ )}
+
+ );
+});
+
+module.exports = SectionsList;
\ No newline at end of file
diff --git a/src/routes/Settings/SectionsList/index.js b/src/routes/Settings/SectionsList/index.js
new file mode 100644
index 000000000..ff7a9b4a0
--- /dev/null
+++ b/src/routes/Settings/SectionsList/index.js
@@ -0,0 +1,3 @@
+const SectionsList = require('./SectionsList');
+
+module.exports = SectionsList;
\ No newline at end of file
diff --git a/src/routes/Settings/SectionsSelector/SectionsSelector.js b/src/routes/Settings/SectionsSelector/SectionsSelector.js
new file mode 100644
index 000000000..2c1f44ced
--- /dev/null
+++ b/src/routes/Settings/SectionsSelector/SectionsSelector.js
@@ -0,0 +1,18 @@
+const React = require('react');
+const { Button } = require('stremio/common');
+const classnames = require('classnames');
+const styles = require('../styles');
+
+const SectionsSelector = ({ className, sections, selectedSectionId, onSelectedSection }) => {
+ return (
+
+ {sections.map((section) =>
+
+ {section.id}
+
+ )}
+
+ );
+};
+
+module.exports = SectionsSelector;
\ No newline at end of file
diff --git a/src/routes/Settings/SectionsSelector/index.js b/src/routes/Settings/SectionsSelector/index.js
new file mode 100644
index 000000000..d873092a7
--- /dev/null
+++ b/src/routes/Settings/SectionsSelector/index.js
@@ -0,0 +1,3 @@
+const SectionsSelector = require('./SectionsSelector');
+
+module.exports = SectionsSelector;
diff --git a/src/routes/Settings/Settings.js b/src/routes/Settings/Settings.js
index d5dd806a7..a892fac6b 100644
--- a/src/routes/Settings/Settings.js
+++ b/src/routes/Settings/Settings.js
@@ -1,128 +1,76 @@
const React = require('react');
-const classnames = require('classnames');
-const { Button, Dropdown, Checkbox, NavBar, ColorInput } = require('stremio/common');
-const Icon = require('stremio-icons/dom/Icon');
+const { NavBar } = require('stremio/common');
const styles = require('./styles');
+const SectionsSelector = require('./SectionsSelector');
+const SectionsList = require('./SectionsList');
+const { settingsSections, SECTIONS_ORDER } = require('./constants');
-const settingsData = [
- { section: 'General', label: 'Username', type: 'user', avatar: '', email: '' },
- { section: 'General', label: 'LOG OUT', type: 'button' },
- { section: 'General', label: 'Change password', type: 'link', href: '' },
- { section: 'General', label: 'Import options', type: 'static-text' },
- { section: 'General', label: 'Import from Facebook', type: 'link', href: '' },
- { section: 'General', label: 'Export user data', type: 'link', href: '' },
- { section: 'General', label: 'Subscribe to calendar', type: 'link', href: '' },
- { section: 'General', label: 'Contact support', type: 'link', href: 'https://stremio.zendesk.com/' },
- { section: 'General', label: 'Request account deletion', type: 'link', href: 'https://docs.google.com/forms/d/e/1FAIpQLScubrlTpDMIPUUBlhZ5lwcXl3HxzKfunIMCX5Jnp-cDyglWjQ/viewform?usp=sf_link' },
- { section: 'General', header: 'Trakt Scrobbling', label: 'AUTHENTICATE', type: 'button', icon: 'ic_trackt' },
- { section: 'General', header: 'UI Language', label: 'UI Language', type: 'select', options: ['Български език', 'English', 'Deutsch', 'Español', 'Italiano'], value: 'English' },
- { section: 'Player', label: 'ADD-ONS', type: 'button', icon: 'ic_addons' },
- { section: 'Player', header: 'Default Subtitles Language', label: 'Default Subtitles Language', type: 'select', options: ['English', 'Nederlands', 'Avesta', 'Български език', 'Deutsch', 'Español', 'Italiano'], value: 'English' },
- { section: 'Player', header: 'Default Subtitles Size', label: 'Default Subtitles Size', type: 'select', options: ['72%', '80%', '100%', '120%', '140%', '160%', '180%'], value: '100%' },
- { section: 'Player', header: 'Subtitles Background', label: 'Subtitles background', type: 'select', options: ['None', 'Solid', 'Transparent'], value: 'None' },
- { section: 'Player', header: 'Subtitles color', label: 'Subtitles color', type: 'color', color: '#FFFFFF' },
- { section: 'Player', header: 'Subtitles outline color', label: 'Subtitles outline color', type: 'color', color: '#000000' },
- { section: 'Player', label: 'Auto-play next episode', type: 'checkbox', value: true },
- { section: 'Player', label: 'Pause playback when minimized', type: 'checkbox', value: false },
- { section: 'Player', label: 'Hardware-accelerated decoding', type: 'checkbox', value: true },
- { section: 'Player', label: 'Launch player in a separate window (advanced)', type: 'checkbox', value: true },
- { section: 'Streaming', header: 'Caching', label: 'Caching', type: 'select', options: ['No Caching', '2GB', '5GB', '10GB'], value: '2GB' },
- { section: 'Streaming', header: 'Torrent Profile', label: 'Torrent Profile', type: 'select', options: ['Default', 'Soft', 'Fast'], value: 'Default' },
- { section: 'Streaming', header: 'Streaming server URL: http://127.0.0.1:11470', label: 'Streaming server is available.', type: 'static-text', icon: 'ic_check' }
-];
-
-const SECTIONS_ORDER = {
- 'General': 1,
- 'Player': 2,
- 'Streaming': 3
+const settingsValues = {
+ "user": null,
+ "ui_language": "eng",
+ "default_subtitles_language": "",
+ "default_subtitles_size": "100%",
+ "subtitles_background": "",
+ "subtitles_color": "#ffffff",
+ "subtitles_outline_color": "#000",
+ "auto-play_next_episode": true,
+ "pause_playback_when_minimized": false,
+ "hardware-accelerated_decoding": true,
+ "launch_player_in_a_separate_window_(advanced)": true,
+ "caching": "2048",
+ "torrent_profile": "profile-default",
+ "streaming_server_is_available.": true,
};
const Settings = () => {
- const [selectedSectionId, setSelectedSectionId] = React.useState(null);
- const [sections, setSections] = React.useState([]);
- const [inputs, setInputs] = React.useState([]);
+ const sections = Object.keys(settingsSections)
+ .sort(function(a, b) {
+ const valueA = SECTIONS_ORDER[a];
+ const valueB = SECTIONS_ORDER[b];
+ if (!isNaN(valueA) && !isNaN(valueB)) return valueA - valueB;
+ if (!isNaN(valueA)) return -1;
+ if (!isNaN(valueB)) return 1;
+ return a - b;
+ })
+ .map((section) => ({
+ id: section,
+ inputs: settingsSections[section].inputs,
+ ref: React.createRef()
+ }));
+ const [selectedSectionId, setSelectedSectionId] = React.useState(sections[0].id);
+ const [preferences, setPreferences] = React.useState(settingsValues);
const scrollContainerRef = React.useRef(null);
- React.useEffect(() => {
- const theSections = settingsData.map(({ section }) => section)
- .filter((section, index, sections) => sections.indexOf(section) === index)
- .sort(function(a, b) {
- const valueA = SECTIONS_ORDER[a];
- const valueB = SECTIONS_ORDER[b];
- if (!isNaN(valueA) && !isNaN(valueB)) return valueA - valueB;
- if (!isNaN(valueA)) return -1;
- if (!isNaN(valueB)) return 1;
- return a - b;
- })
- .map((section) => ({
- id: section,
- ref: React.createRef()
- }));
- setSections(theSections);
-
- if (theSections.length > 0 && (selectedSectionId === null || !theSections.find(({ id }) => id === selectedSectionId))) {
- setSelectedSectionId(theSections[0].id);
- }
-
- setInputs(settingsData.map((setting) => ({
- ...setting,
- id: setting.label,
- ref: React.createRef(),
- active: !!(inputs.find(({ id }) => id === setting.label) || {}).active
- })));
- }, []);
-
/////////////////
- const toggleCheckbox = (id) => {
- setInputs(inputs.map((input) => ({
- ...input,
- value: id === input.id ? !input.value : input.value
- })));
- };
-
- const colorChanged = (id, color) => {
- setInputs(inputs.map((input) => ({
- ...input,
- value: id === input.id ? color : input.value
- })));
- };
-
- const updateDropdown = (event) => {
- var data = event.currentTarget.dataset;
- setInputs(inputs.map((input) => ({
- ...input,
- value: data.name === input.id ? data.value : input.value,
- })));
- };
+ const updatePreference = (option, value) => {
+ const newPrefs = { ...preferences };
+ newPrefs[option] = value;
+ setPreferences(newPrefs);
+ }
const changeSection = (event) => {
const currentSectionId = event.currentTarget.dataset.section;
const section = sections.find((section) => section.id === currentSectionId);
- setSelectedSectionId(currentSectionId);
+ //setSelectedSectionId(currentSectionId);
scrollContainerRef.current.scrollTo({
top: section.ref.current.offsetTop,
behavior: 'smooth'
});
};
-
- const onScroll = (event) => {
- const current = event.currentTarget;
- if (sections.length <= 0) {
- return;
- }
-
- if (current.scrollTop + current.clientHeight === current.scrollHeight) {
+ const updateSection = React.useCallback((event) => {
+ const scrollContainer = event.currentTarget;
+ if (scrollContainer.scrollTop + scrollContainer.clientHeight === scrollContainer.scrollHeight) {
setSelectedSectionId(sections[sections.length - 1].id);
} else {
for (let i = sections.length - 1;i >= 0;i--) {
- if (sections[i].ref.current.offsetTop <= current.scrollTop) {
+ if (sections[i].ref.current.offsetTop <= scrollContainer.scrollTop) {
setSelectedSectionId(sections[i].id);
break;
}
}
}
- };
+ });
return (
@@ -133,91 +81,8 @@ const Settings = () => {
fullscreenButton={true}
navMenu={true} />
-
- {sections.map((section) =>
-
- {section.id}
-
- )}
-
-
- {sections.map((section) =>
-
-
{section.id}
- {inputs.filter((input) => input.section === section.id)
- .map((input) => {
- if (input.type === 'user') {
- return (
-
- {
- input.email.length === 0
- ?
-
- :
-
- }
-
{input.email.length === 0 ? 'Anonymous user' : input.email}
-
- );
- } else if (input.type === 'select') {
- return (
-
- {input.header ?
{input.header}
: null}
- {/* TODO: provide proper data instead of mapping the options */}
-
({ value: o, label: o }))} selected={[input.value]} name={input.id} key={input.id} className={styles['dropdown']} onSelect={updateDropdown} />
-
- );
- } else if (input.type === 'link') {
- return (
-
- {input.header ?
{input.header}
: null}
-
- {input.label}
-
-
- );
- } else if (input.type === 'button') {
- return (
-
- {input.header ?
{input.header}
: null}
-
- {input.icon ? : null}
- {input.label}
-
-
- );
- } else if (input.type === 'checkbox') {
- return (
-
- {input.header ?
{input.header}
: null}
-
- {input.label}
-
-
- );
- } else if (input.type === 'static-text') {
- return (
-
- {input.header ?
{input.header}
: null}
-
- {input.icon ?
: null}
-
{input.label}
-
-
- );
- } else if (input.type === 'color') {
- return (
-
- {input.header ?
{input.header}
: null}
-
- {/*
*/}
-
- );
- }
- })}
-
- )}
-
+
+
);