Skip to content
Projects
Groups
Snippets
Help
Sign in / Register
Toggle navigation
Minds Mobile
Project overview
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
225
Merge Requests
17
Security & Compliance
Packages
Analytics
Wiki
Snippets
Members
Collapse sidebar
Close sidebar
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Minds
Minds Mobile
Commits
cb4cc075
Commit
cb4cc075
authored
1 hour ago
by
Martin Santangelo
Browse files
Options
Download
(feat) theme switch in settings and value stored
parent
022f45f6
feat/themes-support
1 merge request
!513
theme support
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
115 additions
and
69 deletions
+115
-69
App.js
View file @
cb4cc075
...
...
@@ -305,6 +305,11 @@ class App extends Component<Props, State> {
* Render
*/
render
()
{
// App not shown until the theme is loaded
if
(
ThemedStyles
.
theme
===
-
1
)
{
return
null
;
}
const
app
=
(
<
Provider
key
=
"
app
"
{...
stores
}
>
<
ErrorBoundary
message
=
"
An error occurred
"
containerStyle
=
{
CS
.
centered
}
>
...
...
This diff is collapsed.
locales/en.json
View file @
cb4cc075
...
...
@@ -481,7 +481,8 @@
"confirmDeleteKeychain1"
:
"This will delete your Ethereum keychain from this phone. Ensure you backed up the private keys. If you didn't you can lose access to all your funds. There's NO UNDO!"
,
"pushNotification"
:
"Push Notifications"
,
"regenerateKey"
:
"Regenerate messenger keys"
,
"deleteBlockchain"
:
"Delete blockchain keychain"
"deleteBlockchain"
:
"Delete blockchain keychain"
,
"darkMode"
:
"Dark mode"
},
"comingSoon"
:{
"try"
:
"Try the canary app at"
,
...
...
This diff is collapsed.
src/settings/SettingsScreen.js
View file @
cb4cc075
...
...
@@ -31,11 +31,14 @@ import logService from '../common/services/log.service';
import
storageService
from
'
../common/services/storage.service
'
;
import
{
observer
}
from
'
mobx-react/native
'
;
import
ModalPicker
from
'
../common/components/ModalPicker
'
;
import
ThemedStyles
from
'
../styles/ThemedStyles
'
;
import
featuresService
from
'
../common/services/features.service
'
;
const
ICON_SIZE
=
24
;
export
default
@
observer
export
default
class
SettingsScreen
extends
Component
{
class
SettingsScreen
extends
Component
{
static
navigationOptions
=
{
title
:
'
Settings
'
,
...
...
@@ -61,6 +64,14 @@ export default class SettingsScreen extends Component {
settingsStore
.
setLeftHanded
(
!
settingsStore
.
leftHanded
);
}
setDarkMode
=
()
=>
{
if
(
ThemedStyles
.
theme
)
{
ThemedStyles
.
setLight
();
}
else
{
ThemedStyles
.
setDark
();
}
}
wipeEthereumKeychainAction
=
()
=>
{
const
_confirm3
=
async
(
confirmation
)
=>
{
await
new
Promise
(
r
=>
setTimeout
(
r
,
500
));
// Modals have a "cooldown"
...
...
@@ -96,54 +107,55 @@ export default class SettingsScreen extends Component {
};
render
()
{
const
CS
=
ThemedStyles
.
style
;
const
languages
=
i18n
.
getSupportedLocales
();
const
list
=
[
{
name
:
i18n
.
t
(
'
language
'
)
+
` (
${
i18n
.
getCurrentLocale
()}
)`
,
icon
:
(
<
Icon
name
=
'
flag
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
icon
:
(
<
Icon
name
=
'
flag
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
onPress
:
()
=>
{
this
.
showLanguages
();
}
},
{
name
:
i18n
.
t
(
'
auth.password
'
),
icon
:
(
<
Icon
name
=
'
security
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
icon
:
(
<
Icon
name
=
'
security
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
onPress
:
()
=>
{
this
.
props
.
navigation
.
navigate
(
'
SettingsPassword
'
);
}
},
{
name
:
i18n
.
t
(
'
auth.email
'
),
icon
:
(
<
Icon
name
=
'
email
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
icon
:
(
<
Icon
name
=
'
email
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
onPress
:
()
=>
{
this
.
props
.
navigation
.
navigate
(
'
SettingsEmail
'
);
}
},
{
name
:
i18n
.
t
(
'
settings.pushNotification
'
),
icon
:
(
<
Icon
name
=
'
notifications
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
icon
:
(
<
Icon
name
=
'
notifications
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
onPress
:
()
=>
{
this
.
props
.
navigation
.
navigate
(
'
NotificationsSettings
'
);
}
},
{
name
:
i18n
.
t
(
'
settings.blockedChannels
'
),
icon
:
(
<
Icon
name
=
'
block
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
icon
:
(
<
Icon
name
=
'
block
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
onPress
:
()
=>
{
this
.
props
.
navigation
.
navigate
(
'
SettingsBlockedChannels
'
);
}
},
{
name
:
i18n
.
t
(
'
settings.regenerateKey
'
),
icon
:
(
<
Icon
name
=
'
vpn-key
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
icon
:
(
<
Icon
name
=
'
vpn-key
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
onPress
:
()
=>
{
this
.
props
.
navigation
.
navigate
(
'
SettingsRekey
'
);
}
},
{
name
:
i18n
.
t
(
'
settings.logout
'
),
icon
:
(
<
Icon
name
=
'
power-settings-new
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
icon
:
(
<
Icon
name
=
'
power-settings-new
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
onPress
:
()
=>
{
authService
.
logout
();
...
...
@@ -152,78 +164,76 @@ export default class SettingsScreen extends Component {
},
{
name
:
i18n
.
t
(
'
settings.deactivate
'
),
icon
:
(
<
Icon
name
=
'
warning
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
icon
:
(
<
Icon
name
=
'
warning
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
onPress
:
()
=>
{
this
.
props
.
navigation
.
push
(
'
DeleteChannel
'
);
}
},
{
name
:
i18n
.
t
(
'
settings.deleteBlockchain
'
),
icon
:
(
<
Icon
name
=
'
warning
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
icon
:
(
<
Icon
name
=
'
warning
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
onPress
:
this
.
wipeEthereumKeychainAction
},
// ListView used by log package is deprecated
// {
// name: i18n.t('settings.logs'),
// icon: (<Icon name='list' size={ICON_SIZE} style={
styles.icon
}/>),
// icon: (<Icon name='list' size={ICON_SIZE} style={
[styles.icon, CS.colorPrimaryText]
}/>),
// onPress: () => {
// this.props.navigation.push('Logs');
// }
// },
{
name
:
i18n
.
t
(
'
settings.logOnlyErrors
'
),
icon
:
(
<
Icon
name
=
'
list
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
switch
Button
:
true
,
icon
:
(
<
Icon
name
=
'
list
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
switch
:
{
value
:
!
settingsStore
.
appLog
,
onValueChange
:
this
.
appLogActivate
}
,
hideChevron
:
true
,
switched
:
!
settingsStore
.
appLog
,
onSwitch
:
this
.
appLogActivate
},
{
name
:
i18n
.
t
(
'
settings.leftHandedMode
'
),
icon
:
(
<
MaterialCommunityIcons
name
=
'
hand
'
size
=
{
ICON_SIZE
}
style
=
{
styles
.
icon
}
/>
)
,
switch
Button
:
true
,
icon
:
(
<
MaterialCommunityIcons
name
=
'
hand
'
size
=
{
ICON_SIZE
}
style
=
{
[
styles
.
icon
,
CS
.
colorPrimaryText
]
}
/>
)
,
switch
:
{
value
:
settingsStore
.
leftHanded
,
onValueChange
:
this
.
leftHandedActivate
}
,
hideChevron
:
true
,
switched
:
settingsStore
.
leftHanded
,
onSwitch
:
this
.
leftHandedActivate
},
];
if
(
featuresService
.
has
(
'
dark-mode
'
))
{
list
.
push
({
name
:
i18n
.
t
(
'
settings.darkMode
'
),
icon
:
(
<
MaterialCommunityIcons
name
=
'
hand
'
size
=
{
ICON_SIZE
}
style
=
{[
styles
.
icon
,
CS
.
colorPrimaryText
]}
/>
)
,
switch
:
{
value
:
!!
ThemedStyles
.
theme
,
onValueChange
:
this
.
setDarkMode
},
hideChevron
:
true
,
});
}
return
(
<
ScrollView
style
=
{
styles
.
scrollView
}
>
<
ModalPicker
onSelect
=
{
this
.
languageSelected
}
onCancel
=
{
this
.
cancel
}
show
=
{
this
.
state
.
showLanguages
}
title
=
{
i18n
.
t
(
'
language
'
)}
valueField
=
"
value
"
labelField
=
"
name
"
value
=
{
this
.
state
.
language
}
items
=
{
languages
}
/
>
<
View
style
=
{
styles
.
scrollViewContainer
}
>
<
View
style
=
{
styles
.
container
}
>
{
list
.
map
((
l
,
i
)
=>
(
<
ListItem
key
=
{
i
}
title
=
{
l
.
name
}
titleStyle
=
{
styles
.
listTitle
}
containerStyle
=
{
styles
.
listItem
}
subtitle
=
{
l
.
subtitle
}
switchButton
=
{
l
.
switchButton
}
hideChevron
=
{
l
.
hideChevron
}
onSwitch
=
{
l
.
onSwitch
}
switched
=
{
l
.
switched
}
leftIcon
=
{
l
.
icon
}
onPress
=
{
l
.
onPress
}
noBorder
/>
))
}
<
/View
>
<
/View
>
<
/ScrollView
>
<
ScrollView
style
=
{[
styles
.
scrollView
,
CS
.
backgroundThemePrimary
]}
>
<
ModalPicker
onSelect
=
{
this
.
languageSelected
}
onCancel
=
{
this
.
cancel
}
show
=
{
this
.
state
.
showLanguages
}
title
=
{
i18n
.
t
(
'
language
'
)}
valueField
=
"
value
"
labelField
=
"
name
"
value
=
{
this
.
state
.
language
}
items
=
{
languages
}
/
>
{
list
.
map
((
l
,
i
)
=>
(
<
ListItem
key
=
{
i
}
title
=
{
l
.
name
}
titleStyle
=
{[
CS
.
fontL
,
CS
.
colorPrimaryText
,
CS
.
paddingVertical2x
]}
containerStyle
=
{
styles
.
listItem
}
subtitle
=
{
l
.
subtitle
}
hideChevron
=
{
l
.
hideChevron
}
switch
=
{
l
.
switch
}
leftIcon
=
{
l
.
icon
}
onPress
=
{
l
.
onPress
}
/
>
))
}
<
/ScrollView
>
);
}
...
...
@@ -246,10 +256,8 @@ export default class SettingsScreen extends Component {
const
styles
=
StyleSheet
.
create
({
scrollView
:
{
backgroundColor
:
'
#FFF
'
,
flexDirection
:
'
column
'
,
},
scrollViewContainer
:
{
flex
:
1
},
container
:
{
flex
:
1
,
...
...
@@ -258,10 +266,7 @@ const styles = StyleSheet.create({
borderBottomWidth
:
0
,
},
listItem
:
{
borderBottomWidth
:
1
,
borderBottomColor
:
'
#ddd
'
,
paddingTop
:
8
,
paddingBottom
:
8
,
backgroundColor
:
'
transparent
'
//height:20
},
listTitle
:
{
...
...
@@ -269,7 +274,6 @@ const styles = StyleSheet.create({
fontFamily
:
'
Roboto
'
,
},
icon
:
{
color
:
'
#455a64
'
,
alignSelf
:
'
center
'
,
},
...
...
@@ -278,7 +282,7 @@ const styles = StyleSheet.create({
paddingTop
:
8
,
paddingBottom
:
8
,
textAlignVertical
:
'
center
'
,
backgroundColor
:
'
#f4f4f4
'
,
//
backgroundColor: '#f4f4f4',
width
:
'
100%
'
,
//height: 40,
borderTopWidth
:
StyleSheet
.
hairlineWidth
,
...
...
This diff is collapsed.
src/settings/SettingsStore.js
View file @
cb4cc075
import
{
observable
,
action
}
from
'
mobx
'
import
{
observable
,
action
}
from
'
mobx
'
;
import
logService
from
'
../common/services/log.service
'
;
import
storageService
from
'
../common/services/storage.service
'
;
import
appStore
from
'
../../AppStores
'
;
import
ThemedStyles
from
'
../styles/ThemedStyles
'
;
/**
* Store for the values held in Settings.
...
...
@@ -22,8 +22,24 @@ class SettingsStore {
*/
@
action
.
bound
async
init
()
{
const
data
=
await
storageService
.
multiGet
([
'
LeftHanded
'
,
'
AppLog
'
,
'
CreatorNsfw
'
,
'
ConsumerNsfw
'
,
'
UseHashtags
'
]);
if
(
!
data
)
return
;
const
data
=
await
storageService
.
multiGet
([
'
LeftHanded
'
,
'
AppLog
'
,
'
CreatorNsfw
'
,
'
ConsumerNsfw
'
,
'
UseHashtags
'
,
'
Theme
'
,
]);
// store theme changes
ThemedStyles
.
onThemeChange
((
value
)
=>
{
this
.
setTheme
(
value
);
});
if
(
!
data
)
{
ThemedStyles
.
theme
=
0
;
return
;
}
this
.
leftHanded
=
data
[
0
][
1
];
this
.
appLog
=
data
[
1
][
1
];
this
.
creatorNsfw
=
data
[
2
][
1
]
||
[];
...
...
@@ -33,9 +49,20 @@ class SettingsStore {
// set the initial value for hashtag
appStore
.
hashtag
.
setAll
(
!
this
.
useHashtags
);
// theme
ThemedStyles
.
theme
=
data
[
5
][
1
]
||
0
;
return
this
;
}
/**
* Set the theme in the stored values
* @param {numeric} value
*/
setTheme
(
value
)
{
storageService
.
setItem
(
'
Theme
'
,
value
);
}
/**
* Sets in local store and changes this class variable
*/
...
...
This diff is collapsed.
src/styles/ThemedStyles.js
View file @
cb4cc075
import
{
StyleSheet
}
from
'
react-native
'
;
import
{
observable
,
action
}
from
'
mobx
'
;
import
{
observable
,
action
,
reaction
}
from
'
mobx
'
;
import
{
DARK_THEME
,
LIGHT_THEME
}
from
'
./Colors
'
;
...
...
@@ -34,9 +34,12 @@ for (let index = 0; index < repetitions; index++) {
class
ThemedStylesStore
{
/**
* Theme observable
* 1 Dark
* 0 Light
* -1 Not loaded
* @property {Observable<numeric>}
*/
@
observable
theme
=
0
;
@
observable
theme
=
-
1
;
/**
* Style
...
...
@@ -63,6 +66,12 @@ class ThemedStylesStore {
this
.
generateStyle
();
}
onThemeChange
(
fn
)
{
return
reaction
(()
=>
[
this
.
theme
],
async
args
=>
await
fn
(...
args
),
{
fireImmediately
:
false
,
});
}
/**
* Generates the current theme
*/
...
...
This diff is collapsed.
Please
register
or
sign in
to comment