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
179
Merge Requests
16
Security & Compliance
Packages
Wiki
Snippets
Members
Collapse sidebar
Close sidebar
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Minds
Minds Mobile
Commits
9d86db94
Commit
9d86db94
authored
13 minutes ago
by
Juan Manuel Solaro
Browse files
Options
Download
(feat) use discovery store for suggested groups
parent
95f401ef
new-welcome-onboarding
1 merge request
!472
WIP: oboarding/welcome-screen
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
320 additions
and
28 deletions
+320
-28
locales/en.json
View file @
9d86db94
...
...
@@ -264,7 +264,7 @@
"removeOwner"
:
"Remove as Owner"
,
"makeModerator"
:
"Make Moderator"
,
"removeModerator"
:
"Remove as Moderator"
,
"listMembersCount"
:
"
Members {{count}}
"
,
"listMembersCount"
:
"
{{count}} members
"
,
"disableConversations"
:
"Disable conversations"
,
"enableConversations"
:
"Enable conversations"
},
...
...
This diff is collapsed.
src/auth/RegisterFormNew.js
View file @
9d86db94
...
...
@@ -148,7 +148,7 @@ export default class RegisterFormNew extends Component {
<
SubTitle
>
{
i18n
.
to
(
'
auth.alreadyHaveAccount
'
,
null
,
{
login
:
(
<
Text
style
=
{[
ComponentsStyle
.
linkNew
,
CommonStyle
.
fontL
]}
onPress
=
{
this
.
onPress
Back
}
>
<
Text
style
=
{[
ComponentsStyle
.
linkNew
,
CommonStyle
.
fontL
]}
onPress
=
{
this
.
props
.
on
Back
}
>
{
i18n
.
t
(
'
auth.login
'
)}
<
/Text
>
),
...
...
@@ -167,13 +167,6 @@ export default class RegisterFormNew extends Component {
);
}
/**
* On press back
*/
onPressBack
()
{
this
.
props
.
onBack
();
}
/**
* On press register
*/
...
...
This diff is collapsed.
src/common/components/Input.js
View file @
9d86db94
...
...
@@ -48,6 +48,7 @@ export default class Input extends Component {
style
=
{[
ComponentsStyle
.
loginInputNew
,
styles
.
shadow
,
this
.
props
.
style
]}
textStyle
=
{{
color
:
'
#FFFFFF
'
}}
onChangePhoneNumber
=
{
this
.
props
.
onChangeText
}
onEndEditing
=
{
this
.
props
.
onEndEditing
}
ref
=
"
phoneInput
"
placeholder
=
''
/>
...
...
This diff is collapsed.
src/common/components/ListItemButton.js
0 → 100644
View file @
9d86db94
import
React
,
{
Component
}
from
'
react
'
;
import
{
StyleSheet
,
TouchableOpacity
}
from
'
react-native
'
;
export
default
class
ListItemButton
extends
Component
{
render
()
{
return
(
<
TouchableOpacity
onPress
=
{
this
.
props
.
onPress
}
borderRadius
=
{
2
}
style
=
{
styles
.
container
}
>
{
this
.
props
.
children
}
<
/TouchableOpacity
>
);
}
}
const
styles
=
StyleSheet
.
create
({
container
:
{
backgroundColor
:
'
transparent
'
,
borderRadius
:
4
,
borderColor
:
'
#404A4E
'
,
borderWidth
:
1
,
padding
:
4
,
}
});
\ No newline at end of file
This diff is collapsed.
src/common/components/MindsLayout.js
View file @
9d86db94
...
...
@@ -33,7 +33,7 @@ const Container = styled.View`
`
;
const
Body
=
styled
.
View
`
flex:
9
;
flex:
10
;
flex-direction: row;
justify-content: center;
background-color:
${(
props
)
=>
props
.
theme
[
props
.
backgroundColor
]
||
props
.
theme
[
'
primary_background
'
]}
;
...
...
@@ -41,7 +41,7 @@ const Body = styled.View`
`
;
const
Footer
=
styled
.
View
`
flex:
3
;
flex:
2
;
flex-direction: row;
justify-content: center;
background-color:
${(
props
)
=>
props
.
theme
[
props
.
backgroundColor
]
||
props
.
theme
[
'
primary_background
'
]}
;
...
...
This diff is collapsed.
src/groups/GroupsListItemNew.js
0 → 100644
View file @
9d86db94
import
React
,
{
Component
}
from
'
react
'
;
import
{
observer
,
inject
}
from
'
mobx-react/native
'
import
{
MINDS_CDN_URI
}
from
'
../config/Config
'
;
import
{
ListItem
,
Avatar
}
from
'
react-native-elements
'
;
import
colors
from
'
../styles/Colors
'
;
import
i18n
from
'
../common/services/i18n.service
'
;
import
{
CommonStyle
as
CS
}
from
'
../styles/Common
'
;
import
{
FLAG_JOIN
}
from
'
../common/Permissions
'
;
import
{
StyleSheet
}
from
'
react-native
'
;
import
abbrev
from
'
../common/helpers/abbrev
'
;
import
ListItemButton
from
'
../common/components/ListItemButton
'
;
import
Icon
from
'
react-native-vector-icons/MaterialIcons
'
;
import
FastImage
from
'
react-native-fast-image
'
;
export
default
@
inject
(
'
groupView
'
)
@
observer
class
GroupsListItemNew
extends
Component
{
/**
* Render
*/
render
()
{
const
button
=
this
.
getButton
();
return
(
<
ListItem
containerStyle
=
{
styles
.
container
}
title
=
{
this
.
props
.
group
.
name
}
titleStyle
=
{
styles
.
title
}
keyExtractor
=
{
item
=>
item
.
rowKey
}
avatar
=
{
<
FastImage
source
=
{{
uri
:
this
.
getAvatar
(
this
.
props
.
group
)
}}
style
=
{[{
width
:
42
,
height
:
42
,
borderRadius
:
21
,
backgroundColor
:
'
transparent
'
}]}
/
>
}
subtitle
=
{
i18n
.
t
(
'
groups.listMembersCount
'
,
{
count
:
abbrev
(
this
.
props
.
group
[
'
members:count
'
])})}
subtitleStyle
=
{
styles
.
subtitle
}
hideChevron
=
{
!
button
}
rightIcon
=
{
button
}
/
>
);
}
getAvatar
=
(
group
)
=>
{
return
`
${
MINDS_CDN_URI
}
fs/v1/avatars/
${
group
.
guid
}
/large/
${
group
.
icontime
}
`
;
}
/**
* On press
*/
_onPress
=
()
=>
{
if
(
this
.
props
.
onPress
)
{
this
.
props
.
onPress
(
this
.
props
.
group
)
}
}
/**
* Get button
*/
getButton
=
()
=>
{
return
this
.
props
.
group
[
'
is:member
'
]
?
this
.
getLeaveButton
()
:
this
.
getJoinButton
();
}
getJoinButton
=
()
=>
{
return
(
<
ListItemButton
onPress
=
{
this
.
join
}
>
<
Icon
name
=
"
add
"
size
=
{
26
}
color
=
{
'
#A5A5A5
'
}
/
>
<
/ListItemButton
>
);
};
getLeaveButton
=
()
=>
{
return
(
<
ListItemButton
onPress
=
{
this
.
leave
}
>
<
Icon
name
=
"
check
"
size
=
{
26
}
color
=
{
'
#4C92A4
'
}
/
>
<
/ListItemButton
>
);
}
/**
* Join the group
*/
join
=
()
=>
{
if
(
!
this
.
props
.
group
.
can
(
FLAG_JOIN
,
true
))
return
;
this
.
props
.
groupView
.
setGroup
(
this
.
props
.
group
);
this
.
props
.
groupView
.
join
(
this
.
props
.
group
.
guid
);
}
/**
* Leave the group
*/
leave
=
()
=>
{
this
.
props
.
groupView
.
setGroup
(
this
.
props
.
group
);
this
.
props
.
groupView
.
leave
(
this
.
props
.
group
.
guid
);
}
}
const
styles
=
StyleSheet
.
create
({
container
:
{
backgroundColor
:
'
transparent
'
},
title
:
{
color
:
'
#FFF
'
,
fontSize
:
17
,
fontWeight
:
'
500
'
},
subtitle
:
{
color
:
'
#AEB0B8
'
,
fontSize
:
14
,
}
});
This diff is collapsed.
src/onboarding/steps/ChannelSetupStepNew.js
View file @
9d86db94
import
React
,
{
Component
}
from
'
react
'
;
import
{
View
,
Text
,
TouchableHighlight
,
StyleSheet
}
from
'
react-native
'
;
import
{
View
,
Text
,
TouchableHighlight
,
StyleSheet
,
TouchableOpacity
,
Image
}
from
'
react-native
'
;
import
{
observer
,
inject
}
from
'
mobx-react
'
;
import
{
CommonStyle
as
CS
}
from
'
../../styles/Common
'
;
import
i18n
from
'
../../common/services/i18n.service
'
;
import
{
ComponentsStyle
}
from
'
../../styles/Components
'
;
import
{
TouchableOpacity
,
ScrollView
}
from
'
react-native-gesture-handler
'
;
import
{
ScrollView
}
from
'
react-native-gesture-handler
'
;
import
Input
from
'
../../common/components/Input
'
;
import
MindsLayout
from
'
../../common/components/MindsLayout
'
;
...
...
@@ -15,31 +15,142 @@ import { CommonStyled } from '../../styles/CommonStyled';
import
OnboardingButtons
from
'
../OnboardingButtons
'
;
import
OnboardingBackButton
from
'
../OnboardingBackButton
'
;
import
sessionService
from
'
../../common/services/session.service
'
;
import
imagePicker
from
'
../../common/services/image-picker.service
'
;
import
withPreventDoubleTap
from
'
../../common/components/PreventDoubleTap
'
;
import
{
UserError
}
from
'
../../common/UserError
'
;
import
Icon
from
'
react-native-vector-icons/Ionicons
'
;
import
*
as
Progress
from
'
react-native-progress
'
;
const
TouchableCustom
=
withPreventDoubleTap
(
TouchableOpacity
);
@
inject
(
'
channel
'
,
'
user
'
)
@
observer
export
default
class
ChannelSetupStepNew
extends
Component
{
state
=
{
phoneNumber
:
'
+1
'
,
location
:
''
,
birthDate
:
''
,
preview_avatar
:
null
,
preview_banner
:
null
,
saving
:
false
,
dirty
:
false
};
uploads
=
{
avatar
:
null
,
banner
:
null
};
store
;
constructor
(
props
)
{
super
(
props
);
this
.
store
=
this
.
props
.
channel
.
store
(
sessionService
.
guid
);
}
changeAvatarAction
=
async
()
=>
{
try
{
const
response
=
await
imagePicker
.
show
(
'
Select avatar
'
,
'
photo
'
);
if
(
response
)
{
this
.
selectMedia
(
response
);
}
}
catch
(
err
)
{
alert
(
err
);
}
};
selectMedia
(
file
)
{
this
.
setState
({
preview_avatar
:
file
.
uri
});
this
.
store
.
uploadAvatar
(
file
);
this
.
uploads
[
'
avatar
'
]
=
file
;
}
getAvatar
()
{
if
(
this
.
state
.
preview_avatar
)
{
return
{
uri
:
this
.
state
.
preview_avatar
};
}
return
this
.
props
.
user
.
me
.
getAvatarSource
();
}
setPhoneNumber
=
phoneNumber
=>
this
.
setState
({
phoneNumber
});
setLocation
=
location
=>
this
.
setState
({
location
});
setBirthDate
=
birthDate
=>
this
.
setState
({
birthDate
});
save
=
async
()
=>
{
if
(
this
.
store
.
isUploading
)
throw
new
UserError
(
'
Avatar is uploading, please wait
'
);
if
(
!
this
.
state
.
dirty
)
return
;
const
{
phoneNumber
,
location
,
birthDate
}
=
this
.
state
;
payload
=
{
phoneNumber
,
location
,
birthDate
};
this
.
setState
({
saving
:
true
});
const
response
=
await
this
.
store
.
save
(
payload
);
if
(
response
===
true
)
{
await
this
.
props
.
user
.
load
(
true
);
this
.
setState
({
saving
:
false
});
this
.
uploads
=
{
avatar
:
null
,
banner
:
null
};
}
else
if
(
response
===
false
)
{
alert
(
'
Error saving channel
'
);
this
.
setState
({
saving
:
false
});
}
else
{
alert
(
response
)
this
.
setState
({
saving
:
false
});
}
}
getBody
=
()
=>
{
const
hasAvatar
=
this
.
props
.
user
.
hasAvatar
()
||
this
.
state
.
preview_avatar
;
const
avatar
=
this
.
getAvatar
();
return
(
<
View
style
=
{[
CS
.
flexContainer
,
CS
.
columnAlignCenter
]}
>
<
OnboardingBackButton
onBack
=
{
this
.
props
.
onBack
}
/
>
<
View
style
=
{
styles
.
textsContainer
}
>
<
View
style
=
{
[
styles
.
textsContainer
]
}
>
<
Text
style
=
{[
CS
.
onboardingTitle
,
CS
.
marginBottom2x
]}
>
{
i18n
.
t
(
'
onboarding.profileSetup
'
)}
<
/Text
>
<
TitleText
>
{
i18n
.
t
(
'
onboarding.infoTitle
'
)}
<
/TitleText
>
<
Step
>
{
i18n
.
t
(
'
onboarding.step
'
,{
step
:
2
,
total
:
4
})}
<
/Step
>
<
SubTitle
>
{
i18n
.
t
(
'
onboarding.suggestedGroupsDescription
'
)}
<
/SubTitle
>
<
/View
>
<
ScrollView
style
=
{
styles
.
inputContainer
}
>
<
View
style
=
{[
CS
.
padding4x
,
CS
.
flexContainer
,
CS
.
rowJustifyStart
,
CS
.
alignCenter
,
CS
.
marginBottom2x
,
CS
.
marginTop2x
]}
>
<
Text
style
=
{[
CS
.
fontXXL
,
{
color
:
'
#AEB0B8
'
},
CS
.
fontMedium
]}
>
{
i18n
.
t
(
'
onboarding.chooseAvatar
'
)}
<
/Text
>
<
View
style
=
{[
CS
.
rowJustifyEnd
,
CS
.
flexContainer
]}
>
<
TouchableCustom
onPress
=
{
this
.
changeAvatarAction
}
style
=
{[
styles
.
avatar
,
CS
.
marginLeft3x
,
CS
.
border
,
{
borderColor
:
'
#404A4E
'
}
]}
disabled
=
{
this
.
saving
}
testID
=
"
selectAvatar
"
>
{
hasAvatar
&&
<
Image
source
=
{
avatar
}
style
=
{
styles
.
wrappedAvatar
}
/>
}
<
View
style
=
{[
styles
.
tapOverlayView
,
hasAvatar
?
null
:
CS
.
backgroundTransparent
]}
/
>
<
View
style
=
{[
styles
.
overlay
,
CS
.
centered
]}
>
<
Icon
name
=
"
md-cloud-upload
"
size
=
{
40
}
color
=
{
hasAvatar
?
'
#FFF
'
:
'
#404A4E
'
}
/
>
<
/View
>
{(
this
.
store
.
isUploading
&&
this
.
store
.
avatarProgress
)
?
<
View
style
=
{[
styles
.
tapOverlayView
,
styles
.
progress
]}
>
<
Progress
.
Pie
progress
=
{
this
.
store
.
avatarProgress
}
size
=
{
36
}
/
>
<
/View>: null
}
<
/TouchableCustom
>
<
/View
>
<
/View
>
<
Input
placeholder
=
{
i18n
.
t
(
'
onboarding.infoMobileNumber
'
)}
onChangeText
=
{
this
.
setPhoneNumber
}
onEndEditing
=
{(
e
)
=>
console
.
log
(
e
.
nativeEvent
.
text
)}
value
=
{
this
.
state
.
phoneNumber
}
editable
=
{
true
}
optional
=
{
true
}
...
...
@@ -107,11 +218,43 @@ const styles = StyleSheet.create({
justifyContent
:
'
flex-end
'
,
},
inputContainer
:
{
flex
:
6
,
width
:
'
100%
'
,
},
textsContainer
:
{
flex
:
1.5
,
alignItems
:
'
center
'
,
},
avatar
:
{
height
:
90
,
width
:
90
,
borderRadius
:
45
},
progress
:
{
opacity
:
0.8
},
overlay
:
{
position
:
'
absolute
'
,
top
:
0
,
right
:
0
,
bottom
:
0
,
left
:
0
,
},
tapOverlayView
:
{
position
:
'
absolute
'
,
height
:
90
,
width
:
90
,
borderRadius
:
45
,
top
:
0
,
right
:
0
,
bottom
:
0
,
left
:
0
,
backgroundColor
:
'
#000
'
,
opacity
:
0.12
,
alignItems
:
'
center
'
,
justifyContent
:
'
center
'
,
},
wrappedAvatar
:
{
height
:
90
,
width
:
90
,
borderRadius
:
45
}
});
\ No newline at end of file
This diff is collapsed.
src/onboarding/steps/HashtagsStepNew.js
View file @
9d86db94
...
...
@@ -88,10 +88,8 @@ const Step = styled.Text`
const
styles
=
StyleSheet
.
create
({
hashtagContainer
:
{
flex
:
3
,
},
textsContainer
:
{
flex
:
4
,
alignItems
:
'
center
'
,
},
hashtag
:
{
...
...
This diff is collapsed.
src/onboarding/steps/SuggestedGroupsStepNew.js
View file @
9d86db94
...
...
@@ -9,7 +9,7 @@ import {
import
{
observer
,
inject
}
from
'
mobx-react
'
;
import
{
CommonStyle
as
CS
}
from
'
../../styles/Common
'
;
import
GroupsListItem
from
'
../../groups/GroupsListItem
'
;
import
GroupsListItem
New
from
'
../../groups/GroupsListItemNew
'
;
import
i18n
from
'
../../common/services/i18n.service
'
;
import
MindsLayout
from
'
../../common/components/MindsLayout
'
;
...
...
@@ -18,21 +18,28 @@ import { CommonStyled } from '../../styles/CommonStyled';
import
OnboardingButtons
from
'
../OnboardingButtons
'
;
import
OnboardingBackButton
from
'
../OnboardingBackButton
'
;
@
inject
(
'
groups
'
,
'
hashtag
'
)
@
inject
(
'
discovery
'
)
@
observer
export
default
class
SuggestedGroupsStepNew
extends
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
props
.
discovery
.
init
();
}
componentDidMount
()
{
this
.
props
.
hashtag
.
setAll
(
true
);
this
.
props
.
groups
.
reset
();
this
.
props
.
groups
.
loadList
(
'
suggested
'
);
this
.
props
.
discovery
.
filters
.
setType
(
'
groups
'
);
this
.
props
.
discovery
.
filters
.
setPeriod
(
'
30d
'
);
}
renderGroup
=
(
group
)
=>
{
return
<
GroupsListItem
key
=
{
group
.
guid
}
group
=
{
group
}
/
>
return
<
GroupsListItem
New
key
=
{
group
.
guid
}
group
=
{
group
}
/
>
}
getBody
=
()
=>
{
const
discovery
=
this
.
props
.
discovery
;
return
(
<
View
style
=
{[
CS
.
flexContainer
,
CS
.
columnAlignCenter
]}
>
<
OnboardingBackButton
onBack
=
{
this
.
props
.
onBack
}
/
>
...
...
@@ -43,7 +50,7 @@ export default class SuggestedGroupsStepNew extends Component {
<
SubTitle
>
{
i18n
.
t
(
'
onboarding.suggestedGroupsDescription
'
)}
<
/SubTitle
>
<
/View
>
<
ScrollView
style
=
{
styles
.
groupContainer
}
>
{
this
.
props
.
groups
.
list
.
entities
.
map
(
group
=>
this
.
renderGroup
(
group
))}
{
discovery
.
listStore
.
entities
.
slice
()
.
map
(
group
=>
this
.
renderGroup
(
group
))}
<
/ScrollView
>
<
/View
>
);
...
...
@@ -84,11 +91,9 @@ const Step = styled.Text`
const
styles
=
StyleSheet
.
create
({
groupContainer
:
{
flex
:
3.5
,
width
:
'
100%
'
,
},
textsContainer
:
{
flex
:
1.5
,
alignItems
:
'
center
'
,
},
});
\ No newline at end of file
This diff is collapsed.
Please
register
or
sign in
to comment