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
17
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
2 hours 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