mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 14:17:22 +01:00
guilds: generic handling of invitations (incl. accept, reject, invite, etc)
This commit is contained in:
@@ -21,6 +21,16 @@ db.parties.renameCollection('groups',true);
|
|||||||
|
|
||||||
db.groups.update({}, {$set:{type:'party'}}, {multi:true});
|
db.groups.update({}, {$set:{type:'party'}}, {multi:true});
|
||||||
|
|
||||||
|
//migrate invitation mechanisms
|
||||||
|
db.users.update(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
$remove:{party:1},
|
||||||
|
$set:{invitations:{party:null,guilds:[]}}
|
||||||
|
},
|
||||||
|
{multi:1}
|
||||||
|
);
|
||||||
|
|
||||||
tavern = db.tavern.findOne();
|
tavern = db.tavern.findOne();
|
||||||
db.tavern.drop();
|
db.tavern.drop();
|
||||||
|
|
||||||
|
|||||||
@@ -12,14 +12,6 @@ module.exports.app = (appExports, model, app) ->
|
|||||||
|
|
||||||
user = model.at('_user')
|
user = model.at('_user')
|
||||||
|
|
||||||
model.on 'set', '_user.party.invitation', (after, before) ->
|
|
||||||
if !before? and after? # they just got invited
|
|
||||||
partyQ = model.query('groups').withId(after)
|
|
||||||
partyQ.fetch (err, party) ->
|
|
||||||
return next(err) if err
|
|
||||||
model.ref '_party', party
|
|
||||||
browser.resetDom(model)
|
|
||||||
|
|
||||||
appExports.groupCreate = (e,el) ->
|
appExports.groupCreate = (e,el) ->
|
||||||
model.add('groups',
|
model.add('groups',
|
||||||
name: model.get("_newGroup")
|
name: model.get("_newGroup")
|
||||||
@@ -29,33 +21,56 @@ module.exports.app = (appExports, model, app) ->
|
|||||||
, ->location.reload())
|
, ->location.reload())
|
||||||
|
|
||||||
appExports.groupInvite = (e,el) ->
|
appExports.groupInvite = (e,el) ->
|
||||||
id = model.get('_groupInvitee').replace(/[\s"]/g, '')
|
uid = model.get('_groupInvitee').replace(/[\s"]/g, '')
|
||||||
model.set '_groupInvitee', ''
|
model.set '_groupInvitee', ''
|
||||||
return if _.isEmpty(id)
|
return if _.isEmpty(uid)
|
||||||
|
|
||||||
model.query('users').publicInfo([id]).fetch (err, profiles) ->
|
model.query('users').publicInfo([uid]).fetch (err, profiles) ->
|
||||||
throw err if err
|
throw err if err
|
||||||
profile = profiles.at(0)
|
profile = profiles.at(0).get()
|
||||||
return model.set("_groupError", "User with id #{id} not found.") unless profile.get()
|
return model.set("_groupError", "User with id #{uid} not found.") unless profile
|
||||||
|
model.query('groups').withMember(uid).fetch (err, g) ->
|
||||||
|
throw err if err
|
||||||
|
|
||||||
invite = ->
|
{type, name} = e.get()
|
||||||
$.bootstrapGrowl "Invitation Sent."
|
gid = e.get('id')
|
||||||
model.set("users.#{id}.party.invitation", e.get('id'), ->location.reload())
|
groups = g.get()
|
||||||
if e.get('type') is 'party'
|
groupError =(msg) -> model.set("_groupError", msg)
|
||||||
model.query('groups').withMember(id).fetch (err,groups) ->
|
invite = ->
|
||||||
if profile.get('party.invitation') or !_.isEmpty(groups.get())
|
debugger
|
||||||
return model.set("_groupError", "User already in a party or pending invitation.")
|
$.bootstrapGrowl "Invitation Sent."
|
||||||
|
if type is 'guild'
|
||||||
|
model.push("users.#{uid}.invitations.guilds", {id:gid, name}, ->location.reload())
|
||||||
|
else model.set "users.#{uid}.invitations.party", {id:gid, name}, ->
|
||||||
|
debugger
|
||||||
|
location.reload()
|
||||||
|
|
||||||
|
if type is 'guild'
|
||||||
|
if _.find(profile.invitations.guilds, {id:gid})
|
||||||
|
return groupError("User already invited to that group")
|
||||||
|
else if _.find groups, ((group)-> uid in group.members)
|
||||||
|
return groupError("User already in that group")
|
||||||
else invite()
|
else invite()
|
||||||
else invite()
|
if type is 'party'
|
||||||
|
if profile.invitations.party
|
||||||
|
return groupError("User already pending invitation.")
|
||||||
|
else if _.find(groups, {type:'party'})
|
||||||
|
return groupError("User already in a party.")
|
||||||
|
else invite()
|
||||||
|
|
||||||
appExports.partyAccept = ->
|
appExports.acceptInvitation = (e,el) ->
|
||||||
partyId = user.get('party.invitation')
|
group = e.at().get()
|
||||||
user.set 'party.invitation', null, ->
|
pushMember = -> model.push("groups.#{group.id}.members", user.get('id'), ->location.reload())
|
||||||
model.push("groups.#{partyId}.members", user.get('id'), ->location.reload())
|
if $(el).attr('data-type') is 'party'
|
||||||
|
user.set 'invitations.party', null, pushMember
|
||||||
|
else
|
||||||
|
e.at().remove pushMember
|
||||||
|
|
||||||
appExports.partyReject = ->
|
appExports.rejectInvitation = (e, el) ->
|
||||||
user.set 'party.invitation', null
|
clear = -> browser.resetDom(model)
|
||||||
browser.resetDom(model)
|
if e.at().path().indexOf('party') != -1
|
||||||
|
model.del e.at().path(), clear
|
||||||
|
else e.at().remove clear
|
||||||
|
|
||||||
appExports.groupLeave = (e,el) ->
|
appExports.groupLeave = (e,el) ->
|
||||||
members = e.get('members')
|
members = e.get('members')
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ setupSubscriptions = (page, model, params, next, cb) ->
|
|||||||
groupsObj = groups.get()
|
groupsObj = groups.get()
|
||||||
|
|
||||||
# (1) Solo player
|
# (1) Solo player
|
||||||
return finished([selfQ, "groups.habitrpg"], ['_user', '_habitRPG']) if _.isEmpty(groupsObj)
|
return finished(["groups.habitrpg", selfQ], ['_habitRPG', '_user']) if _.isEmpty(groupsObj)
|
||||||
|
|
||||||
## (2) Party or Guild has members, fetch those users too
|
## (2) Party or Guild has members, fetch those users too
|
||||||
# Subscribe to the groups themselves. We separate them by _party, _guilds, and _habitRPG (the "global" guild).
|
# Subscribe to the groups themselves. We separate them by _party, _guilds, and _habitRPG (the "global" guild).
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ userAccess = (store) ->
|
|||||||
return accept(false) # we can only manually set this stuff in the database
|
return accept(false) # we can only manually set this stuff in the database
|
||||||
|
|
||||||
# public access to users.*.party.invitation (TODO, lock down a bit more)
|
# public access to users.*.party.invitation (TODO, lock down a bit more)
|
||||||
if attrPath is 'party.invitation'
|
if attrPath.indexOf('invitations.') is 0
|
||||||
return accept(true)
|
return accept(true)
|
||||||
|
|
||||||
# Same session (user.id = this.session.userId)
|
# Same session (user.id = this.session.userId)
|
||||||
@@ -100,7 +100,7 @@ groupSystem = (store) ->
|
|||||||
@where("id").within(ids)
|
@where("id").within(ids)
|
||||||
.only('stats',
|
.only('stats',
|
||||||
'items',
|
'items',
|
||||||
'party',
|
'invitations',
|
||||||
'profile',
|
'profile',
|
||||||
'achievements',
|
'achievements',
|
||||||
'backer',
|
'backer',
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
<div class="tab-pane" id="challengesViewPublic">
|
<div class="tab-pane" id="challengesViewPublic">
|
||||||
{#each _habitRPG.challenges as :challenge}
|
{#each _habitRPG.challenges as :challenge}
|
||||||
<app:challenges:listing challenge={:challenge} />
|
<app:challenges:listing challenge={:challenge} />
|
||||||
{/}
|
{/}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,13 @@
|
|||||||
<div class="tab-pane active" id="groups-party">
|
<div class="tab-pane active" id="groups-party">
|
||||||
{#if _party.id} <!-- user in a party? -->
|
{#if _party.id} <!-- user in a party? -->
|
||||||
<app:groups:group group={_party} />
|
<app:groups:group group={_party} />
|
||||||
{else if _user.party.invitation}
|
{else if _user.invitations.party}
|
||||||
<!-- TODO show by whom -->
|
<!-- TODO show by whom -->
|
||||||
<h2>You're Invited To {_party.name}</h2>
|
<h2>You're Invited To {_user.invitations.party.name}</h2>
|
||||||
<a class='btn btn-success' x-bind="click: partyAccept">Accept</a>
|
{#with _user.invitations.party}
|
||||||
<a class='btn btn-danger' x-bind="click: partyReject">Reject</a>
|
<a class='btn btn-success' data-type='party' x-bind="click:acceptInvitation">Accept</a>
|
||||||
|
<a class='btn btn-danger' x-bind="click:rejectInvitation">Reject</a>
|
||||||
|
{/}
|
||||||
{else}
|
{else}
|
||||||
<h2>Create A Party</h2>
|
<h2>Create A Party</h2>
|
||||||
<!-- Not in a party , no invites - create a new one -->
|
<!-- Not in a party , no invites - create a new one -->
|
||||||
@@ -30,9 +32,16 @@
|
|||||||
{/}
|
{/}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
|
|
||||||
<div class='tab-pane active' id='groups-guild-create'>
|
<div class='tab-pane active' id='groups-guild-create'>
|
||||||
|
{#each _user.invitations.guilds as :invitation}
|
||||||
|
<h3>You're Invited To {:invitation.name}</h3>
|
||||||
|
<a class='btn btn-success' data-type='guild' x-bind="click:acceptInvitation">Accept</a>
|
||||||
|
<a class='btn btn-danger' x-bind="click:rejectInvitation">Reject</a>
|
||||||
|
{/}
|
||||||
<app:groups:create-group type='guild' />
|
<app:groups:create-group type='guild' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#each _guilds as :guild}
|
{#each _guilds as :guild}
|
||||||
<div class="tab-pane" id="groups-guild-{:guild.id}">
|
<div class="tab-pane" id="groups-guild-{:guild.id}">
|
||||||
<app:groups:group group={:guild} />
|
<app:groups:group group={:guild} />
|
||||||
|
|||||||
Reference in New Issue
Block a user