2017-06-02 20:55:02 +00:00
< template lang = "pug" >
2017-09-07 19:26:53 +00:00
. row ( v - if = "group._id" )
2017-08-22 05:04:56 +00:00
group - form - modal ( v - if = 'isParty' )
2017-08-01 18:52:49 +00:00
invite - modal ( : group = 'this.group' )
2017-07-29 22:08:36 +00:00
start - quest - modal ( : group = 'this.group' )
2017-09-30 13:28:39 +00:00
quest - details - modal ( : group = 'this.group' )
2017-10-02 01:42:02 +00:00
group - gems - modal
2017-09-30 13:34:25 +00:00
. col - 12. col - sm - 8. standard - page
2017-06-02 20:55:02 +00:00
. row
2017-06-27 20:02:55 +00:00
. col - 6. title - details
h1 { { group . name } }
strong . float - left ( v - once ) { { $t ( 'groupLeader' ) } }
2017-09-25 18:02:12 +00:00
span . leader . float - left ( v - if = 'group.leader.profile' , @ click = 'showMemberProfile(group.leader)' ) : { { group . leader . profile . name } }
2017-06-02 20:55:02 +00:00
. col - 6
2017-06-27 20:02:55 +00:00
. row . icon - row
2017-07-29 22:08:36 +00:00
. col - 4. offset - 4 ( v - bind : class = "{ 'offset-8': isParty }" )
. item - with - icon ( @ click = "showMemberModal()" )
2017-08-09 16:56:48 +00:00
. svg - icon . shield ( v - html = "icons.goldGuildBadgeIcon" , v - if = 'group.memberCount > 1000' )
. svg - icon . shield ( v - html = "icons.silverGuildBadgeIcon" , v - if = 'group.memberCount > 100 && group.memberCount < 999' )
. svg - icon . shield ( v - html = "icons.bronzeGuildBadgeIcon" , v - if = 'group.memberCount < 100' )
2017-09-25 18:02:12 +00:00
span . number { { group . memberCount | abbrNum } }
2017-10-02 01:42:02 +00:00
div ( v - once ) { { $t ( 'memberList' ) } }
2017-07-29 22:08:36 +00:00
. col - 4 ( v - if = '!isParty' )
2017-10-02 01:42:02 +00:00
. item - with - icon ( @ click = 'showGroupGems()' )
2017-06-27 20:02:55 +00:00
. svg - icon . gem ( v - html = "icons.gem" )
2017-08-09 16:56:48 +00:00
span . number { { group . balance * 4 } }
2017-06-27 20:02:55 +00:00
div ( v - once ) { { $t ( 'guildBank' ) } }
2017-06-02 20:55:02 +00:00
. row . chat - row
. col - 12
h3 ( v - once ) { { $t ( 'chat' ) } }
2017-09-01 21:26:10 +00:00
. row . new - message - row
2017-12-05 20:05:01 +00:00
textarea ( : placeholder = "!isParty ? $t('chatPlaceholder') : $t('partyChatPlaceholder')" , v - model = 'newMessage' , @ keydown = 'updateCarretPosition' , @ keyup . ctrl . enter = 'sendMessage()' )
2017-09-01 21:26:10 +00:00
autocomplete ( : text = 'newMessage' , v - on : select = "selectedAutocomplete" , : coords = 'coords' , : chat = 'group.chat' )
2017-10-01 04:54:12 +00:00
2017-09-25 18:02:12 +00:00
. row
. col - 6
button . btn . btn - secondary . float - left . fetch ( v - once , @ click = 'fetchRecentMessages()' ) { { $t ( 'fetchRecentMessages' ) } }
button . btn . btn - secondary . float - left ( v - once , @ click = 'reverseChat()' ) { { $t ( 'reverseChat' ) } }
2017-10-01 04:54:12 +00:00
. col - 6
button . btn . btn - secondary . send - chat . float - right ( v - once , @ click = 'sendMessage()' ) { { $t ( 'send' ) } }
2017-09-01 21:26:10 +00:00
2017-09-12 04:00:34 +00:00
. row . community - guidelines ( v - if = '!communityGuidelinesAccepted' )
div . col - 8 ( v - once , v - html = "$t('communityGuidelinesIntro')" )
div . col - 4
button . btn . btn - info ( @ click = 'acceptCommunityGuidelines()' , v - once ) { { $t ( 'acceptCommunityGuidelines' ) } }
2017-09-01 21:26:10 +00:00
. row
. col - 12. hr
chat - message ( : chat . sync = 'group.chat' , : group - id = 'group._id' , group - name = 'group.name' )
2017-09-30 13:34:25 +00:00
. col - 12. col - sm - 4. sidebar
2017-08-03 20:04:03 +00:00
. row ( : class = '{"guild-background": !isParty}' )
2017-06-02 20:55:02 +00:00
. col - 6
. col - 6
2017-06-27 20:02:55 +00:00
. button - container
2017-08-26 02:56:21 +00:00
button . btn . btn - success ( class = 'btn-success' , v - if = 'isLeader && !group.purchased.active' , @ click = 'upgradeGroup()' )
| { { $t ( 'upgrade' ) } }
2017-06-27 20:02:55 +00:00
. button - container
2017-10-04 02:15:00 +00:00
button . btn . btn - primary ( b - btn , @ click = "updateGuild" , v - once , v - if = 'isLeader || isAdmin' ) { { $t ( 'edit' ) } }
2017-06-27 20:02:55 +00:00
. button - container
2017-08-09 16:56:48 +00:00
button . btn . btn - success ( class = 'btn-success' , v - if = '!isMember' , @ click = 'join()' ) { { $t ( 'join' ) } }
2017-06-27 20:02:55 +00:00
. button - container
2017-07-25 14:24:40 +00:00
button . btn . btn - primary ( v - once , @ click = 'showInviteModal()' ) { { $t ( 'invite' ) } }
2017-10-04 02:15:00 +00:00
// @TODO: hide the invitation button if there's an active group plan and the player is not the leader
2017-06-27 20:02:55 +00:00
. button - container
2017-10-04 02:15:00 +00:00
// @TODO: V2 button.btn.btn-primary(v-once, v-if='!isLeader') {{$t('messageGuildLeader')}} // Suggest making the button visible to the leader too - useful for them to test how the feature works or to send a note to themself. -- Alys
2017-06-27 20:02:55 +00:00
. button - container
2017-10-04 02:15:00 +00:00
// @TODO: V2 button.btn.btn-primary(v-once, v-if='isMember && !isParty') {{$t('donateGems')}} // Suggest removing the isMember restriction - it's okay if non-members donate to a public guild. Also probably allow it for parties if parties can buy imagery. -- Alys
2017-06-27 20:02:55 +00:00
2017-07-29 22:08:36 +00:00
. section - header ( v - if = 'isParty' )
2017-06-27 20:02:55 +00:00
. row
. col - 10
h3 ( v - once ) { { $t ( 'questDetailsTitle' ) } }
. col - 2
. toggle - up ( @ click = "sections.quest = !sections.quest" , v - if = "sections.quest" )
. svg - icon ( v - html = "icons.upIcon" )
. toggle - down ( @ click = "sections.quest = !sections.quest" , v - if = "!sections.quest" )
. svg - icon ( v - html = "icons.downIcon" )
. section ( v - if = "sections.quest" )
. row . no - quest - section ( v - if = 'isParty && !onPendingQuest && !onActiveQuest' )
. col - 12. text - center
. svg - icon ( v - html = "icons.questIcon" )
2017-08-26 16:53:10 +00:00
h4 ( v - once ) { { $t ( 'youAreNotOnQuest' ) } }
2017-06-27 20:02:55 +00:00
p ( v - once ) { { $t ( 'questDescription' ) } }
2017-10-04 02:15:00 +00:00
button . btn . btn - secondary ( v - once , @ click = "openStartQuestModal()" ) { { $t ( 'startAQuest' ) } }
2017-06-27 20:02:55 +00:00
. row . quest - active - section ( v - if = 'isParty && onPendingQuest && !onActiveQuest' )
2017-09-30 13:28:39 +00:00
. col - 2
. quest ( : class = '`inventory_quest_scroll_${questData.key}`' )
. col - 6. titles
strong { { questData . text ( ) } }
p { { acceptedCount } } / { { group . memberCount } }
. col - 4
button . btn . btn - secondary ( @ click = "openQuestDetails()" ) { { $t ( 'details' ) } }
2017-10-09 19:40:45 +00:00
. row . quest - active - section . quest - invite ( v - if = 'user.party.quest && user.party.quest.RSVPNeeded' )
span { { $t ( 'wouldYouParticipate' ) } }
button . btn . btn - primary . accept ( @ click = 'questAccept(group._id)' ) { { $t ( 'accept' ) } }
button . btn . btn - primary . reject ( @ click = 'questReject(group._id)' ) { { $t ( 'reject' ) } }
2017-06-27 20:02:55 +00:00
. row . quest - active - section ( v - if = 'isParty && !onPendingQuest && onActiveQuest' )
. col - 12. text - center
. quest - boss ( : class = "'quest_' + questData.key" )
h3 ( v - once ) { { questData . text ( ) } }
2017-08-29 20:23:09 +00:00
. quest - box
. collect - info ( v - if = 'questData.collect' )
. row ( v - for = '(value, key) in questData.collect' )
. col - 2
div ( : class = "'quest_' + questData.key + '_' + key" )
. col - 10
strong { { value . text ( ) } }
. grey - progress - bar
. collect - progress - bar ( : style = "{width: (group.quest.progress.collect[key] / value.count) * 100 + '%'}" )
strong { { group . quest . progress . collect [ key ] } } / { { value . count } }
. boss - info ( v - if = 'questData.boss' )
. row
2017-06-27 20:02:55 +00:00
. col - 6
2017-08-29 20:23:09 +00:00
h4 . float - left ( v - once ) { { questData . boss . name ( ) } }
2017-06-27 20:02:55 +00:00
. col - 6
2017-08-29 20:23:09 +00:00
span . float - right ( v - once ) { { $t ( 'participantsTitle' ) } }
. row
. col - 12
. grey - progress - bar
. boss - health - bar ( : style = "{width: (group.quest.progress.hp / questData.boss.hp) * 100 + '%'}" )
. row . boss - details
. col - 6
span . float - left
| { { parseFloat ( group . quest . progress . hp ) . toFixed ( 2 ) } } / { { parseFloat ( questData . boss . hp ) . toFixed ( 2 ) } }
2017-11-30 18:37:31 +00:00
. col - 6 ( v - if = 'userIsOnQuest' )
2017-09-12 17:56:06 +00:00
// @TODO: Why do we not sync quset progress on the group doc? Each user could have different progress
2017-09-25 18:02:12 +00:00
span . float - right { { parseFloat ( user . party . quest . progress . up ) . toFixed ( 1 ) || 0 } } pending damage
2017-09-06 23:28:52 +00:00
. row . rage - bar - row ( v - if = 'questData.boss.rage' )
. col - 12
. grey - progress - bar
2017-10-14 01:32:55 +00:00
. boss - health - bar . rage - bar ( : style = "{width: (group.quest.progress.rage / questData.boss.rage.value) * 100 + '%'}" )
2017-09-06 23:28:52 +00:00
. row . boss - details . rage - details ( v - if = 'questData.boss.rage' )
. col - 6
2017-10-14 01:32:55 +00:00
span . float - left { { $t ( 'rage' ) } } { { parseFloat ( group . quest . progress . rage ) . toFixed ( 2 ) } } / { { questData . boss . rage . value } }
2017-10-04 02:15:00 +00:00
button . btn . btn - secondary ( v - once , @ click = "questAbort()" , v - if = 'canEditQuest' ) { { $t ( 'abort' ) } }
2017-06-27 20:02:55 +00:00
2017-09-25 18:02:12 +00:00
. section - header ( v - if = '!isParty' )
2017-06-27 20:02:55 +00:00
. row
. col - 10
2017-08-22 20:39:45 +00:00
h3 ( v - once ) { { $t ( 'guildSummary' ) } }
2017-06-27 20:02:55 +00:00
. col - 2
2017-08-22 20:39:45 +00:00
. toggle - up ( @ click = "sections.summary = !sections.summary" , v - if = "sections.summary" )
2017-06-27 20:02:55 +00:00
. svg - icon ( v - html = "icons.upIcon" )
2017-08-22 20:39:45 +00:00
. toggle - down ( @ click = "sections.summary = !sections.summary" , v - if = "!sections.summary" )
2017-06-27 20:02:55 +00:00
. svg - icon ( v - html = "icons.downIcon" )
2017-08-22 20:39:45 +00:00
. section ( v - if = "sections.summary" )
2017-09-13 18:31:23 +00:00
p ( v - markdown = 'group.summary' )
2017-06-27 20:02:55 +00:00
. section - header
. row
. col - 10
2017-08-22 20:39:45 +00:00
h3 { { $t ( 'groupDescription' ) } }
2017-06-27 20:02:55 +00:00
. col - 2
2017-08-22 20:39:45 +00:00
. toggle - up ( @ click = "sections.description = !sections.description" , v - if = "sections.description" )
2017-06-27 20:02:55 +00:00
. svg - icon ( v - html = "icons.upIcon" )
2017-08-22 20:39:45 +00:00
. toggle - down ( @ click = "sections.description = !sections.description" , v - if = "!sections.description" )
2017-06-27 20:02:55 +00:00
. svg - icon ( v - html = "icons.downIcon" )
2017-08-22 20:39:45 +00:00
. section ( v - if = "sections.description" )
2017-08-23 19:36:43 +00:00
p ( v - markdown = 'group.description' )
2017-06-27 20:02:55 +00:00
. section - header . challenge
. row
. col - 10. information - header
h3 ( v - once )
| { { $t ( 'challenges' ) } }
2017-09-01 13:15:54 +00:00
# groupPrivateDescOrChallengeInfo . icon . tooltip - wrapper ( : title = "isParty ? $t('challengeDetails') : $t('privateDescription')" )
2017-06-27 20:02:55 +00:00
. svg - icon ( v - html = 'icons.information' )
2017-09-01 13:15:54 +00:00
b - tooltip (
: title = "isParty ? $t('challengeDetails') : $t('privateDescription')" ,
target = "groupPrivateDescOrChallengeInfo" ,
)
2017-06-27 20:02:55 +00:00
. col - 2
. toggle - up ( @ click = "sections.challenges = !sections.challenges" , v - if = "sections.challenges" )
. svg - icon ( v - html = "icons.upIcon" )
. toggle - down ( @ click = "sections.challenges = !sections.challenges" , v - if = "!sections.challenges" )
. svg - icon ( v - html = "icons.downIcon" )
. section ( v - if = "sections.challenges" )
2017-07-29 22:08:36 +00:00
group - challenges ( : groupId = 'searchId' )
2017-06-27 20:02:55 +00:00
div . text - center
2017-09-25 18:02:12 +00:00
button . btn . btn - danger ( v - if = 'isMember' , @ click = 'clickLeave()' ) { { $t ( 'leave' ) } }
2017-06-02 20:55:02 +00:00
< / template >
< style lang = "scss" scoped >
2017-06-27 20:02:55 +00:00
@ import '~client/assets/scss/colors.scss' ;
2017-06-02 20:55:02 +00:00
2017-12-01 13:47:45 +00:00
@ media ( min - width : 1300 px ) {
. standard - page {
2017-12-04 17:24:04 +00:00
max - width : calc ( 100 % - 430 px ) ;
2017-12-01 13:47:45 +00:00
}
. sidebar {
max - width : 430 px ! important ;
}
}
2017-07-29 22:08:36 +00:00
h1 {
color : $purple - 200 ;
}
2017-09-25 18:02:12 +00:00
. leader : hover {
cursor : pointer ;
}
2017-06-27 20:02:55 +00:00
. button - container {
margin - bottom : 1 em ;
2017-06-02 20:55:02 +00:00
2017-06-27 20:02:55 +00:00
button {
width : 100 % ;
}
}
. item - with - icon {
border - radius : 2 px ;
background - color : # ffffff ;
box - shadow : 0 2 px 2 px 0 rgba ( 26 , 24 , 29 , 0.16 ) , 0 1 px 4 px 0 rgba ( 26 , 24 , 29 , 0.12 ) ;
padding : 1 em ;
2017-07-29 22:08:36 +00:00
text - align : center ;
. svg - icon . shield , . svg - icon . gem {
2017-08-21 15:36:31 +00:00
width : 28 px ;
2017-07-29 22:08:36 +00:00
margin : 0 auto ;
2017-07-31 19:54:52 +00:00
display : inline - block ;
2017-08-21 15:36:31 +00:00
vertical - align : bottom ;
margin - right : 0.5 em ;
2017-07-29 22:08:36 +00:00
}
. number {
font - size : 22 px ;
font - weight : bold ;
}
}
. item - with - icon : hover {
cursor : pointer ;
2017-06-27 20:02:55 +00:00
}
2017-06-02 20:55:02 +00:00
2017-06-27 20:02:55 +00:00
. sidebar {
background - color : $gray - 600 ;
2017-07-29 22:08:36 +00:00
padding - bottom : 2 em ;
2017-06-02 20:55:02 +00:00
}
2017-06-27 20:02:55 +00:00
. card {
margin : 2 em 0 ;
padding : 1 em ;
h3 . leader {
color : $purple - 200 ;
}
. text {
font - size : 16 px ;
line - height : 1.43 ;
color : $gray - 50 ;
}
}
. guild - background {
2017-07-31 19:54:52 +00:00
background - image : url ( '~assets/images/groups/grassy-meadow-backdrop.png' ) ;
height : 246 px ;
2017-06-27 20:02:55 +00:00
}
textarea {
height : 150 px ;
width : 100 % ;
background - color : $white ;
border : solid 1 px $gray - 400 ;
2017-06-02 20:55:02 +00:00
font - size : 16 px ;
line - height : 1.43 ;
2017-06-27 20:02:55 +00:00
color : $gray - 300 ;
padding : .5 em ;
2017-06-02 20:55:02 +00:00
}
2017-06-27 20:02:55 +00:00
2017-08-07 20:26:17 +00:00
textarea : : - webkit - input - placeholder { /* Chrome/Opera/Safari */
font - style : italic ;
}
textarea : : - moz - placeholder { /* Firefox 19+ */
font - style : italic ;
}
textarea : - ms - input - placeholder { /* IE 10+ */
font - style : italic ;
}
textarea : - moz - placeholder { /* Firefox 18- */
font - style : italic ;
}
2017-06-27 20:02:55 +00:00
. title - details {
padding - top : 1 em ;
padding - left : 1 em ;
}
. icon - row {
margin - top : 1 em ;
. number {
font - size : 22 px ;
font - weight : bold ;
}
}
. chat - row {
margin - top : 2 em ;
2017-09-12 04:00:34 +00:00
. community - guidelines {
background - color : rgba ( 135 , 129 , 144 , 0.84 ) ;
padding : 1 em ;
color : $white ;
position : absolute ;
top : 0 ;
height : 150 px ;
padding - top : 3 em ;
margin - top : 2.3 em ;
width : 100 % ;
border - radius : 4 px ;
}
2017-09-01 21:26:10 +00:00
. new - message - row {
position : relative ;
}
2017-06-27 20:02:55 +00:00
}
2017-07-29 22:08:36 +00:00
. toggle - up . svg - icon , . toggle - down . svg - icon {
width : 25 px ;
2017-06-27 20:02:55 +00:00
}
2017-06-02 20:55:02 +00:00
2017-06-27 20:02:55 +00:00
span . action {
font - size : 14 px ;
line - height : 1.33 ;
color : $gray - 200 ;
font - weight : 500 ;
2017-06-08 19:04:19 +00:00
margin - right : 1 em ;
2017-06-02 20:55:02 +00:00
}
2017-06-27 20:02:55 +00:00
span . action . icon {
margin - right : .3 em ;
}
. no - quest - section {
padding : 2 em ;
color : $gray - 300 ;
h4 {
color : $gray - 300 ;
}
p {
margin - bottom : 2 em ;
}
. svg - icon {
height : 30 px ;
width : 30 px ;
2017-07-29 22:08:36 +00:00
margin : 0 auto ;
2017-06-27 20:02:55 +00:00
margin - bottom : 2 em ;
}
}
. information - header {
h3 , . tooltip - wrapper {
display : inline - block ;
}
. tooltip - wrapper {
2017-08-07 20:26:17 +00:00
width : 15 px ;
margin - left : 1.2 em ;
2017-06-27 20:02:55 +00:00
}
}
. quest - active - section {
2017-09-30 13:28:39 +00:00
. titles {
padding - top : .5 em ;
}
2017-06-27 20:02:55 +00:00
. quest - box {
2017-08-29 20:23:09 +00:00
background - image : url ( '~client/assets/svg/for-css/quest-border.svg' ) ;
background - size : 100 % 100 % ;
2017-06-27 20:02:55 +00:00
width : 100 % ;
2017-08-29 20:23:09 +00:00
padding : .5 em ;
margin - bottom : 1 em ;
2017-06-27 20:02:55 +00:00
svg : {
width : 100 % ;
height : 100 % ;
}
}
. boss - info , . collect - info {
2017-08-29 20:23:09 +00:00
width : 90 % ;
margin : 0 auto ;
2017-06-27 20:02:55 +00:00
text - align : left ;
}
}
2017-10-09 19:40:45 +00:00
. quest - invite {
background - color : # 2995 cd ;
color : # fff ;
padding : 1 em ;
span {
margin - top : .3 em ;
font - size : 14 px ;
font - weight : bold ;
}
. accept , . reject {
padding : .2 em 1 em ;
font - size : 12 px ;
height : 24 px ;
border - radius : 2 px ;
box - shadow : 0 2 px 2 px 0 rgba ( 26 , 24 , 29 , 0.16 ) , 0 1 px 4 px 0 rgba ( 26 , 24 , 29 , 0.12 ) ;
}
. accept {
background - color : # 24 cc8f ;
margin - left : 4 em ;
margin - right : .5 em ;
}
. reject {
border - radius : 2 px ;
background - color : # f74e52 ;
}
}
2017-06-27 20:02:55 +00:00
. section - header {
border - top : 1 px solid # e1e0e3 ;
margin - top : 1 em ;
padding - top : 1 em ;
}
. section - header . challenge {
border - bottom : 1 px solid # e1e0e3 ;
margin - bottom : 1 em ;
padding - bottom : 1 em ;
}
. toggle - up , . toggle - down {
cursor : pointer ;
}
. quest - boss {
margin : 0 auto ;
}
. boss - health - bar {
width : 80 % ;
background - color : red ;
height : 15 px ;
margin - bottom : .5 em ;
}
2017-09-06 23:28:52 +00:00
. rage - details {
margin - bottom : 1 em ;
}
. boss - health - bar . rage - bar {
margin - top : 1 em ;
background - color : orange ;
}
2017-07-29 22:08:36 +00:00
. grey - progress - bar {
width : 100 % ;
height : 15 px ;
background - color : # e1e0e3 ;
}
2017-06-27 20:02:55 +00:00
. collect - progress - bar {
background - color : # 24 cc8f ;
height : 15 px ;
2017-09-25 18:02:12 +00:00
max - width : 100 % ;
2017-06-27 20:02:55 +00:00
}
2017-09-01 21:26:10 +00:00
. hr {
width : 100 % ;
height : 20 px ;
border - bottom : 1 px solid $gray - 500 ;
text - align : center ;
margin : 2 em 0 ;
}
2017-06-02 20:55:02 +00:00
< / style >
< script >
2017-09-30 13:28:39 +00:00
// @TODO: Break this down into components
2017-09-29 21:03:43 +00:00
import debounce from 'lodash/debounce' ;
2017-08-18 20:29:49 +00:00
import extend from 'lodash/extend' ;
2017-06-02 20:55:02 +00:00
import groupUtilities from 'client/mixins/groupsUtilities' ;
2017-07-29 22:08:36 +00:00
import styleHelper from 'client/mixins/styleHelper' ;
2017-06-02 20:55:02 +00:00
import { mapState } from 'client/libs/store' ;
2017-09-08 19:23:58 +00:00
import * as Analytics from 'client/libs/analytics' ;
2017-06-02 20:55:02 +00:00
import membersModal from './membersModal' ;
2017-07-29 22:08:36 +00:00
import startQuestModal from './startQuestModal' ;
2017-09-30 13:28:39 +00:00
import questDetailsModal from './questDetailsModal' ;
2017-06-27 20:02:55 +00:00
import quests from 'common/script/content/quests' ;
import percent from 'common/script/libs/percent' ;
import groupFormModal from './groupFormModal' ;
2017-07-25 14:24:40 +00:00
import inviteModal from './inviteModal' ;
2017-07-21 17:00:36 +00:00
import chatMessage from '../chat/chatMessages' ;
2017-08-07 20:26:17 +00:00
import autocomplete from '../chat/autoComplete' ;
2017-07-26 15:05:13 +00:00
import groupChallenges from '../challenges/groupChallenges' ;
2017-10-02 01:42:02 +00:00
import groupGemsModal from 'client/components/groups/groupGemsModal' ;
2017-08-23 19:36:43 +00:00
import markdownDirective from 'client/directives/markdown' ;
2017-06-27 20:02:55 +00:00
2017-06-08 19:04:19 +00:00
import deleteIcon from 'assets/svg/delete.svg' ;
import copyIcon from 'assets/svg/copy.svg' ;
import likeIcon from 'assets/svg/like.svg' ;
import likedIcon from 'assets/svg/liked.svg' ;
import reportIcon from 'assets/svg/report.svg' ;
import gemIcon from 'assets/svg/gem.svg' ;
2017-06-27 20:02:55 +00:00
import questIcon from 'assets/svg/quest.svg' ;
import informationIcon from 'assets/svg/information.svg' ;
import questBackground from 'assets/svg/quest-background-border.svg' ;
import upIcon from 'assets/svg/up.svg' ;
import downIcon from 'assets/svg/down.svg' ;
2017-08-09 16:56:48 +00:00
import goldGuildBadgeIcon from 'assets/svg/gold-guild-badge-small.svg' ;
import silverGuildBadgeIcon from 'assets/svg/silver-guild-badge-small.svg' ;
import bronzeGuildBadgeIcon from 'assets/svg/bronze-guild-badge-small.svg' ;
2017-06-08 19:04:19 +00:00
2017-06-02 20:55:02 +00:00
export default {
2017-07-29 22:08:36 +00:00
mixins : [ groupUtilities , styleHelper ] ,
2017-07-21 17:00:36 +00:00
props : [ 'groupId' ] ,
2017-06-02 20:55:02 +00:00
components : {
membersModal ,
2017-07-29 22:08:36 +00:00
startQuestModal ,
2017-06-27 20:02:55 +00:00
groupFormModal ,
2017-07-21 17:00:36 +00:00
chatMessage ,
2017-07-25 14:24:40 +00:00
inviteModal ,
2017-07-26 15:05:13 +00:00
groupChallenges ,
2017-08-07 20:26:17 +00:00
autocomplete ,
2017-09-30 13:28:39 +00:00
questDetailsModal ,
2017-10-02 01:42:02 +00:00
groupGemsModal ,
2017-06-27 20:02:55 +00:00
} ,
directives : {
2017-08-23 19:36:43 +00:00
markdown : markdownDirective ,
2017-06-02 20:55:02 +00:00
} ,
data ( ) {
return {
2017-09-07 19:26:53 +00:00
searchId : '' ,
group : { } ,
2017-06-08 19:04:19 +00:00
icons : Object . freeze ( {
like : likeIcon ,
copy : copyIcon ,
report : reportIcon ,
delete : deleteIcon ,
gem : gemIcon ,
liked : likedIcon ,
2017-06-27 20:02:55 +00:00
questIcon ,
information : informationIcon ,
questBackground ,
upIcon ,
downIcon ,
2017-07-29 22:08:36 +00:00
goldGuildBadgeIcon ,
2017-08-09 16:56:48 +00:00
silverGuildBadgeIcon ,
bronzeGuildBadgeIcon ,
2017-06-08 19:04:19 +00:00
} ) ,
2017-06-27 20:02:55 +00:00
selectedQuest : { } ,
sections : {
quest : true ,
2017-08-22 20:39:45 +00:00
summary : true ,
2017-06-27 20:02:55 +00:00
description : true ,
challenges : true ,
} ,
2017-07-21 17:00:36 +00:00
newMessage : '' ,
2017-08-07 20:26:17 +00:00
coords : {
TOP : 0 ,
LEFT : 0 ,
} ,
2017-06-02 20:55:02 +00:00
} ;
} ,
computed : {
... mapState ( { user : 'user.data' } ) ,
2017-11-30 18:37:31 +00:00
userIsOnQuest ( ) {
if ( ! this . group . quest || ! this . group . quest . members ) return false ;
return Boolean ( this . group . quest . members [ this . user . _id ] ) ;
} ,
2017-09-30 13:28:39 +00:00
acceptedCount ( ) {
let count = 0 ;
if ( ! this . group || ! this . group . quest ) return count ;
for ( let uuid in this . group . quest . members ) {
if ( this . group . quest . members [ uuid ] ) count += 1 ;
}
return count ;
} ,
2017-09-12 04:00:34 +00:00
communityGuidelinesAccepted ( ) {
return this . user . flags . communityGuidelinesAccepted ;
} ,
2017-07-31 19:54:52 +00:00
partyStore ( ) {
return this . $store . state . party ;
} ,
2017-06-27 20:02:55 +00:00
isParty ( ) {
return this . $route . path . startsWith ( '/party' ) ;
} ,
onPendingQuest ( ) {
return Boolean ( this . group . quest . key ) && ! this . group . quest . active ;
} ,
onActiveQuest ( ) {
return this . group . quest . active ;
} ,
isLeader ( ) {
return this . user . _id === this . group . leader . _id ;
} ,
2017-10-04 02:15:00 +00:00
isAdmin ( ) {
return Boolean ( this . user . contributor . admin ) ;
} ,
2017-06-02 20:55:02 +00:00
isMember ( ) {
2017-06-27 20:02:55 +00:00
return this . isMemberOfGroup ( this . user , this . group ) ;
} ,
canEditQuest ( ) {
2017-10-04 02:15:00 +00:00
if ( ! this . group . quest ) return false ;
let isQuestLeader = this . group . quest . leader === this . user . _id ;
let isPartyLeader = this . group . leader . _id === this . user . _id ;
return isQuestLeader || isPartyLeader ;
2017-06-02 20:55:02 +00:00
} ,
isMemberOfPendingQuest ( ) {
let userid = this . user . _id ;
2017-06-27 20:02:55 +00:00
let group = this . group ;
2017-06-02 20:55:02 +00:00
if ( ! group . quest || ! group . quest . members ) return false ;
if ( group . quest . active ) return false ; // quest is started, not pending
return userid in group . quest . members && group . quest . members [ userid ] !== false ;
} ,
isMemberOfRunningQuest ( ) {
let userid = this . user . _id ;
2017-06-27 20:02:55 +00:00
let group = this . group ;
2017-06-02 20:55:02 +00:00
if ( ! group . quest || ! group . quest . members ) return false ;
if ( ! group . quest . active ) return false ; // quest is pending, not started
return group . quest . members [ userid ] ;
} ,
memberProfileName ( memberId ) {
let foundMember = find ( this . group . members , function findMember ( member ) {
return member . _id === memberId ;
} ) ;
return foundMember . profile . name ;
} ,
isManager ( memberId , group ) {
return Boolean ( group . managers [ memberId ] ) ;
} ,
userCanApprove ( userId , group ) {
if ( ! group ) return false ;
let leader = group . leader . _id === userId ;
let userIsManager = Boolean ( group . managers [ userId ] ) ;
return leader || userIsManager ;
} ,
2017-06-27 20:02:55 +00:00
hasChallenges ( ) {
if ( ! this . group . challenges ) return false ;
return this . group . challenges . length === 0 ;
} ,
bossHpPercent ( ) {
return percent ( this . group . quest . progress . hp , this . questData . boss . hp ) ;
} ,
2017-07-29 22:08:36 +00:00
questData ( ) {
if ( ! this . group . quest ) return { } ;
return quests . quests [ this . group . quest . key ] ;
} ,
2017-06-02 20:55:02 +00:00
} ,
2017-07-31 19:54:52 +00:00
mounted ( ) {
2017-09-05 18:34:00 +00:00
if ( ! this . searchId ) this . searchId = this . groupId ;
this . load ( ) ;
2017-08-18 20:29:49 +00:00
2017-09-05 18:34:00 +00:00
if ( this . user . newMessages [ this . searchId ] ) {
this . $store . dispatch ( 'chat:markChatSeen' , { groupId : this . searchId } ) ;
2017-09-23 00:30:37 +00:00
this . $delete ( this . user . newMessages , this . searchId ) ;
2017-09-05 18:34:00 +00:00
}
} ,
beforeRouteUpdate ( to , from , next ) {
2017-09-07 19:26:53 +00:00
this . $set ( this , 'searchId' , to . params . groupId ) ;
2017-09-05 18:34:00 +00:00
next ( ) ;
2017-06-02 20:55:02 +00:00
} ,
watch : {
// call again the method if the route changes (when this route is already active)
$route : 'fetchGuild' ,
2017-07-31 19:54:52 +00:00
partyStore ( ) {
if ( this . $store . state . party . _id ) {
this . group = this . $store . state . party ;
} else {
this . group = null ;
this . $router . push ( '/' ) ;
}
} ,
2017-06-02 20:55:02 +00:00
} ,
methods : {
2017-09-12 04:00:34 +00:00
acceptCommunityGuidelines ( ) {
this . $store . dispatch ( 'user:set' , { 'flags.communityGuidelinesAccepted' : true } ) ;
} ,
2017-09-05 18:34:00 +00:00
load ( ) {
if ( this . isParty ) {
this . searchId = 'party' ;
// @TODO: Set up from old client. Decide what we need and what we don't
// Check Desktop notifs
// Load invites
}
this . fetchGuild ( ) ;
this . $root . $on ( 'updatedGroup' , group => {
let updatedGroup = extend ( this . group , group ) ;
this . $set ( this . group , updatedGroup ) ;
} ) ;
} ,
2017-08-07 20:26:17 +00:00
// @TODO: abstract autocomplete
// https://medium.com/@_jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a
getCoord ( e , text ) {
let carPos = text . selectionEnd ;
let div = document . createElement ( 'div' ) ;
let span = document . createElement ( 'span' ) ;
let copyStyle = getComputedStyle ( text ) ;
[ ] . forEach . call ( copyStyle , ( prop ) => {
div . style [ prop ] = copyStyle [ prop ] ;
} ) ;
div . style . position = 'absolute' ;
document . body . appendChild ( div ) ;
div . textContent = text . value . substr ( 0 , carPos ) ;
span . textContent = text . value . substr ( carPos ) || '.' ;
div . appendChild ( span ) ;
this . coords = {
TOP : span . offsetTop ,
LEFT : span . offsetLeft ,
} ;
document . body . removeChild ( div ) ;
} ,
2017-09-29 21:03:43 +00:00
updateCarretPosition : debounce ( function updateCarretPosition ( eventUpdate ) {
this . _updateCarretPosition ( eventUpdate ) ;
} , 250 ) ,
_updateCarretPosition ( eventUpdate ) {
2017-08-07 20:26:17 +00:00
let text = eventUpdate . target ;
this . getCoord ( eventUpdate , text ) ;
} ,
selectedAutocomplete ( newText ) {
this . newMessage = newText ;
} ,
2017-07-29 22:08:36 +00:00
showMemberModal ( ) {
2017-08-23 03:58:13 +00:00
this . $store . state . memberModalOptions . groupId = this . group . _id ;
this . $store . state . memberModalOptions . group = this . group ;
2017-11-08 17:40:37 +00:00
this . $root . $emit ( 'bv::show::modal' , 'members-modal' ) ;
2017-07-29 22:08:36 +00:00
} ,
2017-07-21 17:00:36 +00:00
async sendMessage ( ) {
2017-09-25 18:02:12 +00:00
if ( ! this . newMessage ) return ;
2017-07-21 17:00:36 +00:00
let response = await this . $store . dispatch ( 'chat:postChat' , {
2017-09-10 21:55:35 +00:00
group : this . group ,
2017-07-21 17:00:36 +00:00
message : this . newMessage ,
} ) ;
this . group . chat . unshift ( response . message ) ;
this . newMessage = '' ;
} ,
2017-08-03 20:04:03 +00:00
fetchRecentMessages ( ) {
this . fetchGuild ( ) ;
} ,
2017-10-04 02:15:00 +00:00
reverseChat ( ) {
this . group . chat . reverse ( ) ;
} ,
2017-06-02 20:55:02 +00:00
updateGuild ( ) {
2017-06-27 20:02:55 +00:00
this . $store . state . editingGroup = this . group ;
2017-11-08 17:40:37 +00:00
this . $root . $emit ( 'bv::show::modal' , 'guild-form' ) ;
2017-06-02 20:55:02 +00:00
} ,
2017-07-25 14:24:40 +00:00
showInviteModal ( ) {
2017-11-08 17:40:37 +00:00
this . $root . $emit ( 'bv::show::modal' , 'invite-modal' ) ;
2017-07-25 14:24:40 +00:00
} ,
2017-06-02 20:55:02 +00:00
async fetchGuild ( ) {
2017-07-31 19:54:52 +00:00
if ( this . searchId === 'party' && ! this . user . party . _id ) {
2017-11-08 17:40:37 +00:00
this . $root . $emit ( 'bv::show::modal' , 'create-party-modal' ) ;
2017-07-31 19:54:52 +00:00
return ;
}
2017-07-29 22:08:36 +00:00
let group = await this . $store . dispatch ( 'guilds:getGroup' , { groupId : this . searchId } ) ;
2017-09-25 18:02:12 +00:00
2017-06-27 20:02:55 +00:00
if ( this . isParty ) {
2017-09-12 17:56:06 +00:00
this . $store . state . party . data = group ;
this . group = this . $store . state . party . data ;
2017-06-27 20:02:55 +00:00
this . checkForAchievements ( ) ;
return ;
}
2017-09-07 19:26:53 +00:00
this . $set ( this , 'group' , group ) ;
2017-06-02 20:55:02 +00:00
} ,
deleteAllMessages ( ) {
if ( confirm ( this . $t ( 'confirmDeleteAllMessages' ) ) ) {
// User.clearPMs();
}
} ,
2017-06-27 20:02:55 +00:00
openStartQuestModal ( ) {
2017-11-08 17:40:37 +00:00
this . $root . $emit ( 'bv::show::modal' , 'start-quest-modal' ) ;
2017-06-27 20:02:55 +00:00
} ,
2017-09-30 13:28:39 +00:00
openQuestDetails ( ) {
2017-11-08 17:40:37 +00:00
this . $root . $emit ( 'bv::show::modal' , 'quest-details' ) ;
2017-09-30 13:28:39 +00:00
} ,
2017-06-27 20:02:55 +00:00
checkForAchievements ( ) {
// Checks if user's party has reached 2 players for the first time.
if ( ! this . user . achievements . partyUp && this . group . memberCount >= 2 ) {
// @TODO
// User.set({'achievements.partyUp':true});
// Achievement.displayAchievement('partyUp');
}
// Checks if user's party has reached 4 players for the first time.
if ( ! this . user . achievements . partyOn && this . group . memberCount >= 4 ) {
// @TODO
// User.set({'achievements.partyOn':true});
// Achievement.displayAchievement('partyOn');
}
} ,
async join ( ) {
2017-08-23 03:58:13 +00:00
if ( this . group . cancelledPlan && ! confirm ( this . $t ( 'aboutToJoinCancelledGroupPlan' ) ) ) {
2017-06-27 20:02:55 +00:00
return ;
}
2017-08-09 16:56:48 +00:00
await this . $store . dispatch ( 'guilds:join' , { guildId : this . group . _id , type : 'myGuilds' } ) ;
this . user . guilds . push ( this . group . _id ) ;
2017-06-27 20:02:55 +00:00
} ,
clickLeave ( ) {
2017-09-08 19:23:58 +00:00
Analytics . track ( {
hitType : 'event' ,
eventCategory : 'button' ,
eventAction : 'click' ,
eventLabel : 'Leave Party' ,
} ) ;
2017-06-27 20:02:55 +00:00
// @TODO: Get challenges and ask to keep or remove
2017-08-09 16:56:48 +00:00
if ( ! confirm ( 'Are you sure you want to leave?' ) ) return ;
2017-06-27 20:02:55 +00:00
let keep = true ;
this . leave ( keep ) ;
} ,
async leave ( keepTasks ) {
let keepChallenges = 'remain-in-challenges' ;
2017-07-31 19:54:52 +00:00
let data = {
2017-06-27 20:02:55 +00:00
groupId : this . group . _id ,
keep : keepTasks ,
keepChallenges ,
2017-07-31 19:54:52 +00:00
} ;
2017-09-08 19:23:58 +00:00
if ( this . isParty ) {
data . type = 'party' ;
Analytics . updateUser ( { partySize : null , partyID : null } ) ;
2017-09-25 18:02:12 +00:00
this . $store . state . party . members = [ ] ;
2017-09-08 19:23:58 +00:00
}
2017-07-31 19:54:52 +00:00
await this . $store . dispatch ( 'guilds:leave' , data ) ;
2017-06-27 20:02:55 +00:00
} ,
2017-08-26 02:56:21 +00:00
upgradeGroup ( ) {
this . $store . state . upgradingGroup = this . group ;
this . $router . push ( '/group-plans' ) ;
} ,
2017-06-27 20:02:55 +00:00
// @TODO: Move to notificatin component
async leaveOldPartyAndJoinNewParty ( ) {
let newPartyName = 'where does this come from' ;
if ( ! confirm ( ` Are you sure you want to delete your party and join ${ newPartyName } ? ` ) ) return ;
let keepChallenges = 'remain-in-challenges' ;
await this . $store . dispatch ( 'guilds:leave' , {
groupId : this . group . _id ,
keep : false ,
keepChallenges ,
} ) ;
await this . $store . dispatch ( 'guilds:join' , { groupId : this . group . _id } ) ;
} ,
clickStartQuest ( ) {
2017-09-08 19:23:58 +00:00
Analytics . track ( {
hitType : 'event' ,
eventCategory : 'button' ,
eventAction : 'click' ,
eventLabel : 'Start a Quest' ,
} ) ;
2017-06-27 20:02:55 +00:00
let hasQuests = find ( this . user . items . quests , ( quest ) => {
return quest > 0 ;
} ) ;
if ( hasQuests ) {
2017-11-08 17:40:37 +00:00
this . $root . $emit ( 'bv::show::modal' , 'start-quest-modal' ) ;
2017-06-27 20:02:55 +00:00
return ;
}
// $rootScope.$state.go('options.inventory.quests');
} ,
2017-09-25 18:02:12 +00:00
async showMemberProfile ( leader ) {
let heroDetails = await this . $store . dispatch ( 'members:fetchMember' , { memberId : leader . _id } ) ;
2017-11-27 16:29:20 +00:00
this . $root . $emit ( 'habitica:show-profile' , {
user : heroDetails . data . data ,
startingPage : 'profile' ,
} ) ;
2017-09-25 18:02:12 +00:00
} ,
2017-06-27 20:02:55 +00:00
async questAbort ( ) {
if ( ! confirm ( this . $t ( 'sureAbort' ) ) ) return ;
if ( ! confirm ( this . $t ( 'doubleSureAbort' ) ) ) return ;
let quest = await this . $store . dispatch ( 'quests:sendAction' , { groupId : this . group . _id , action : 'quests/abort' } ) ;
this . group . quest = quest ;
} ,
async questLeave ( ) {
if ( ! confirm ( this . $t ( 'sureLeave' ) ) ) return ;
let quest = await this . $store . dispatch ( 'quests:sendAction' , { groupId : this . group . _id , action : 'quests/leave' } ) ;
this . group . quest = quest ;
} ,
2017-10-09 19:40:45 +00:00
async questAccept ( partyId ) {
let quest = await this . $store . dispatch ( 'quests:sendAction' , { groupId : partyId , action : 'quests/accept' } ) ;
this . user . party . quest = quest ;
2017-06-27 20:02:55 +00:00
} ,
2017-10-09 19:40:45 +00:00
async questReject ( partyId ) {
let quest = await this . $store . dispatch ( 'quests:sendAction' , { groupId : partyId , action : 'quests/reject' } ) ;
this . user . party . quest = quest ;
2017-06-27 20:02:55 +00:00
} ,
2017-10-02 01:42:02 +00:00
showGroupGems ( ) {
2017-11-08 17:40:37 +00:00
this . $root . $emit ( 'bv::show::modal' , 'group-gems-modal' ) ;
2017-10-02 01:42:02 +00:00
} ,
2017-06-02 20:55:02 +00:00
} ,
} ;
< / script >