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
224
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
21 minutes 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