User preferences #104

Merged
v0l merged 2 commits from preferences into main 2023-01-20 20:10:17 +00:00
6 changed files with 295 additions and 292 deletions
Showing only changes of commit 87c2baf135 - Show all commits

View File

@ -6,7 +6,7 @@ import { faBell, faMessage } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { RootState } from "State/Store";
import { init, UserPreferences } from "State/Login";
import { init, setPreferences, UserPreferences } from "State/Login";
import { HexKey, RawEvent, TaggedRawEvent } from "Nostr";
import { RelaySettings } from "Nostr/Connection";
import { System } from "Nostr/System"
@ -39,14 +39,26 @@ export default function Layout() {
}
}, [relays]);
useEffect(() => {
function setTheme(theme: "light" | "dark") {
const elm = document.documentElement;
if (prefs.theme === "light") {
if (theme === "light" && !elm.classList.contains("light")) {
elm.classList.add("light");
} else {
} else if (theme === "dark" && elm.classList.contains("light")) {
elm.classList.remove("light");
}
}, [prefs]);
}
useEffect(() => {
let osTheme = window.matchMedia("(prefers-color-scheme: light)");
setTheme(prefs.theme === "system" && osTheme.matches ? "light" : prefs.theme === "light" ? "light" : "dark");
osTheme.onchange = (e) => {
if (prefs.theme === "system") {
setTheme(e.matches ? "light" : "dark");
}
}
return () => { osTheme.onchange = null; }
}, [prefs.theme]);
useEffect(() => {
dispatch(init());

View File

@ -8,10 +8,10 @@ export default function SettingsPage() {
const navigate = useNavigate();
return (
<div className="settings-page">
<h2 onClick={() => navigate("/settings")}>Settings</h2>
<>
<h2 onClick={() => navigate("/settings")} className="pointer">Settings</h2>
<Outlet />
</div>
</>
);
}

View File

@ -1,3 +1,3 @@
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
.settings-nav h3 {
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
background-color: var(--note-bg);
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
.settings-nav .card {
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
cursor: pointer;
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
}

View File

@ -16,7 +16,8 @@ const PreferencesPage = () => {
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div>Theme</div>
</div>
<div>
<select value={perf.theme} onChange={e => dispatch(setPreferences({ ...perf, theme: "light" === e.target.value ? "light" : "dark" }))}>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<select value={perf.theme} onChange={e => dispatch(setPreferences({ ...perf, theme: e.target.value} as UserPreferences))}>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<option value="system">System (Default)</option>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>

verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.

View File

@ -24,7 +24,7 @@ export interface UserPreferences {
/**
* Select between light/dark theme
*/
theme: "light" | "dark",
theme: "system" | "light" | "dark",
/**
* Ask for confirmation when reposting notes
@ -103,7 +103,7 @@ const InitState = {
preferences: {
enableReactions: true,
autoLoadMedia: true,
theme: "dark",
theme: "system",
confirmReposts: false
}
} as LoginStore;
@ -146,10 +146,6 @@ const LoginSlice = createSlice({
let pref = window.localStorage.getItem(UserPreferencesKey);
if (pref) {
state.preferences = JSON.parse(pref);
} else {
// get os defaults
const osTheme = window.matchMedia("(prefers-color-scheme: light)");
state.preferences.theme = osTheme.matches ? "light" : "dark";
}
},
setPrivateKey: (state, action: PayloadAction<HexKey>) => {

View File

@ -92,316 +92,310 @@ code {
}
@media (min-width: 720px) {
<<<<<<< HEAD .card {
.card {
margin-bottom: 24px;
padding: 12px 24px;
}
}
@media (prefers-color-scheme: light) {
.card {
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.05);
html.light .card {
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.05);
}
=======.card {
margin-bottom: 24px;
padding: 24px;
>>>>>>>3e41614 (feat: user preferences)
}
}
.card .header {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.card .header {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.card>.footer {
display: flex;
flex-direction: row-reverse;
margin-top: 12px;
}
.card>.footer {
display: flex;
flex-direction: row-reverse;
margin-top: 12px;
}
.btn {
padding: 10px;
border-radius: 5px;
cursor: pointer;
user-select: none;
background-color: var(--bg-color);
color: var(--font-color);
border: 1px solid;
display: inline-block;
}
.btn {
padding: 10px;
border-radius: 5px;
cursor: pointer;
user-select: none;
background-color: var(--bg-color);
color: var(--font-color);
border: 1px solid;
display: inline-block;
}
.btn-warn {
border-color: var(--error);
}
.btn-warn {
border-color: var(--error);
}
.btn-success {
border-color: var(--success);
}
.btn-success {
border-color: var(--success);
}
.btn.active {
border: 2px solid;
background-color: var(--gray-secondary);
color: var(--font-color);
font-weight: bold;
}
.btn.active {
border: 2px solid;
background-color: var(--gray-secondary);
color: var(--font-color);
font-weight: bold;
}
.btn.disabled {
color: var(--gray-light);
}
.btn.disabled {
color: var(--gray-light);
}
.btn:hover {
background-color: var(--gray);
}
.btn:hover {
background-color: var(--gray);
}
.btn-sm {
padding: 5px;
}
.btn-sm {
padding: 5px;
}
.btn-rnd {
border-radius: 100%;
}
.btn-rnd {
border-radius: 100%;
}
textarea {
font: inherit;
}
textarea {
font: inherit;
}
input[type="text"], input[type="password"], input[type="number"], textarea, select {
padding: 10px;
border-radius: 5px;
border: 0;
background-color: var(--gray);
color: var(--font-color);
}
input[type="text"], input[type="password"], input[type="number"], textarea, select {
padding: 10px;
border-radius: 5px;
border: 0;
background-color: var(--gray);
color: var(--font-color);
}
input[type="checkbox"] {
width: 24px;
height: 24px;
}
input[type="checkbox"] {
width: 24px;
height: 24px;
}
input:disabled {
color: var(--gray-medium);
cursor: not-allowed;
}
input:disabled {
color: var(--gray-medium);
cursor: not-allowed;
}
textarea:placeholder {
color: var(--gray-superlight);
}
textarea:placeholder {
color: var(--gray-superlight);
}
.flex {
display: flex;
align-items: center;
min-width: 0;
}
.flex {
display: flex;
align-items: center;
min-width: 0;
}
.f-center {
justify-content: center;
}
.f-center {
justify-content: center;
}
.f-1 {
flex: 1;
}
.f-1 {
flex: 1;
}
.f-2 {
flex: 2;
}
.f-2 {
flex: 2;
}
.f-grow {
flex-grow: 1;
min-width: 0;
}
.f-grow {
flex-grow: 1;
min-width: 0;
}
.f-shrink {
flex-shrink: 1;
}
.f-shrink {
flex-shrink: 1;
}
.f-ellipsis {
min-width: 0;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.f-ellipsis {
min-width: 0;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.f-col {
flex-direction: column;
align-items: flex-start !important;
}
.f-col {
flex-direction: column;
align-items: flex-start !important;
}
.w-max {
width: 100%;
width: -moz-available;
width: -webkit-fill-available;
width: fill-available;
}
.w-max {
width: 100%;
width: -moz-available;
width: -webkit-fill-available;
width: fill-available;
}
.w-max-w {
max-width: 100%;
max-width: -moz-available;
max-width: -webkit-fill-available;
max-width: fill-available;
}
.w-max-w {
max-width: 100%;
max-width: -moz-available;
max-width: -webkit-fill-available;
max-width: fill-available;
}
a {
color: inherit;
line-height: 1.3em;
}
a {
color: inherit;
line-height: 1.3em;
}
a.ext {
word-break: break-all;
white-space: initial;
a.ext {
word-break: break-all;
white-space: initial;
}
div.form-group {
display: flex;
align-items: center;
}
div.form-group>div {
padding: 3px 5px;
word-break: break-word;
}
div.form-group>div:nth-child(1) {
min-width: 100px;
}
div.form-group>div:nth-child(2) {
display: flex;
flex-grow: 1;
justify-content: end;
}
div.form-group>div:nth-child(2) input {
flex-grow: 1;
}
.modal {
position: absolute;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.8);
}
.modal .modal-content {
display: flex;
justify-content: center;
}
.modal .modal-content>div {
padding: 10px;
border-radius: 10px;
background-color: var(--gray);
margin-top: 5vh;
}
body.scroll-lock {
overflow: hidden;
height: 100vh;
}
.m5 {
margin: 5px;
}
.m10 {
margin: 10px;
}
.mr10 {
margin-right: 10px;
}
.mr5 {
margin-right: 5px;
}
.ml5 {
margin-left: 5px;
}
.mb10 {
margin-bottom: 10px;
}
.tabs {
display: flex;
align-content: center;
text-align: center;
margin: 10px 0;
overflow-x: auto;
}
.tabs>div {
margin-right: 10px;
cursor: pointer;
}
.tabs>div:last-child {
margin: 0;
}
.tabs .active {
font-weight: bold;
}
.error {
color: var(--error);
}
.bg-error {
background-color: var(--error);
}
.bg-success {
background-color: var(--success);
}
.root-tabs {
padding: 0;
align-items: center;
justify-content: flex-start;
}
.root-tab {
border-bottom: 3px solid var(--gray-secondary);
}
.root-tab.active {
border-bottom: 3px solid var(--highlight);
}
.tweet {
display: flex;
align-items: center;
justify-content: center;
}
.tweet div {
width: 100%;
}
.tweet div .twitter-tweet {
margin: 0 auto;
}
.tweet div .twitter-tweet>iframe {
max-height: unset;
}
@media(max-width: 720px) {
.page {
width: calc(100vw - 8px);
}
div.form-group {
display: flex;
align-items: center;
flex-direction: column;
align-items: flex-start;
}
}
div.form-group>div {
padding: 3px 5px;
word-break: break-word;
}
div.form-group>div:nth-child(1) {
min-width: 100px;
}
div.form-group>div:nth-child(2) {
display: flex;
flex-grow: 1;
justify-content: end;
}
div.form-group>div:nth-child(2) input {
flex-grow: 1;
}
.modal {
position: absolute;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.8);
}
.modal .modal-content {
display: flex;
justify-content: center;
}
.modal .modal-content>div {
padding: 10px;
border-radius: 10px;
background-color: var(--gray);
margin-top: 5vh;
}
body.scroll-lock {
overflow: hidden;
height: 100vh;
}
.m5 {
margin: 5px;
}
.m10 {
margin: 10px;
}
.mr10 {
margin-right: 10px;
}
.mr5 {
margin-right: 5px;
}
.ml5 {
margin-left: 5px;
}
.mb10 {
margin-bottom: 10px;
}
.tabs {
display: flex;
align-content: center;
text-align: center;
margin: 10px 0;
overflow-x: auto;
}
.tabs>div {
margin-right: 10px;
cursor: pointer;
}
.tabs>div:last-child {
margin: 0;
}
.tabs .active {
font-weight: bold;
}
.error {
color: var(--error);
}
.bg-error {
background-color: var(--error);
}
.bg-success {
background-color: var(--success);
}
.root-tabs {
padding: 0;
align-items: center;
justify-content: flex-start;
}
.root-tab {
border-bottom: 3px solid var(--gray-secondary);
}
.root-tab.active {
border-bottom: 3px solid var(--highlight);
}
.tweet {
display: flex;
align-items: center;
justify-content: center;
}
.tweet div {
width: 100%;
}
.tweet div .twitter-tweet {
margin: 0 auto;
}
.tweet div .twitter-tweet>iframe {
max-height: unset;
}
@media(max-width: 720px) {
.page {
width: calc(100vw - 8px);
}
div.form-group {
flex-direction: column;
align-items: flex-start;
}
}
.highlight {
color: var(--highlight);
}
.highlight {
color: var(--highlight);
}