-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NEW] Experimental Game Center (externalComponents implementation) (#…
- Loading branch information
Showing
28 changed files
with
1,167 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Meteor } from 'meteor/meteor'; | ||
import { Session } from 'meteor/session'; | ||
import { AppsEngineUIHost } from '@rocket.chat/apps-engine/client/AppsEngineUIHost'; | ||
|
||
import { Rooms } from '../../models/client'; | ||
import { APIClient } from '../../utils/client'; | ||
import { getUserAvatarURL } from '../../utils/lib/getUserAvatarURL'; | ||
|
||
export class RealAppsEngineUIHost extends AppsEngineUIHost { | ||
constructor() { | ||
super(); | ||
|
||
this._baseURL = document.baseURI.slice(0, -1); | ||
} | ||
|
||
getUserAvatarUrl(username) { | ||
const avatarUrl = getUserAvatarURL(username); | ||
|
||
if (!avatarUrl.startsWith('http') && !avatarUrl.startsWith('data')) { | ||
return `${ this._baseURL }${ avatarUrl }`; | ||
} | ||
|
||
return avatarUrl; | ||
} | ||
|
||
async getClientRoomInfo() { | ||
const { name: slugifiedName, _id: id } = Rooms.findOne(Session.get('openedRoom')); | ||
|
||
let cachedMembers = []; | ||
try { | ||
const { members } = await APIClient.get('v1/groups.members', { roomId: id }); | ||
|
||
cachedMembers = members.map(({ _id, username }) => ({ | ||
id: _id, | ||
username, | ||
avatarUrl: this.getUserAvatarUrl(username), | ||
})); | ||
} catch (error) { | ||
console.warn(error); | ||
} | ||
|
||
return { | ||
id, | ||
slugifiedName, | ||
members: cachedMembers, | ||
}; | ||
} | ||
|
||
async getClientUserInfo() { | ||
const { username, _id } = Meteor.user(); | ||
|
||
return { | ||
id: _id, | ||
username, | ||
avatarUrl: this.getUserAvatarUrl(username), | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<template name="GameCenter"> | ||
{{#table onScroll=onTableScroll onResize=onTableResize onSort=onTableSort}} | ||
<tbody class="rc-game__list"> | ||
<thead> | ||
<tr> | ||
<th class="js-sort rc-table-td--medium" data-sort="name"> | ||
<div class="table-fake-th">{{_ "Name"}}</div> | ||
</th> | ||
<th class="rc-table-td"> | ||
<div class="table-fake-th">{{_ "Description"}} </div> | ||
</th> | ||
</tr> | ||
</thead> | ||
{{#each games}} | ||
<tr class="rc-game-center__game" data-name="{{name}}"> | ||
<td> | ||
<div class="rc-table-wrapper"> | ||
{{#if icon}} | ||
<div class="rc-table-avatar" style="background-image:url({{icon}})"></div> | ||
{{/if}} | ||
<div class="rc-table-info"> | ||
<span class="rc-table-title"> | ||
{{name}} | ||
</span> | ||
</div> | ||
</div> | ||
</td> | ||
<td> | ||
<div class="rc-table-wrapper"> | ||
<div class="rc-table-info"> | ||
<span class="rc-table-title"> | ||
{{#if summary}} | ||
{{summary}} | ||
{{else}} | ||
{{description}} | ||
{{/if}} | ||
</span> | ||
{{#if summary}} | ||
<span class="rc-table-subtitle"> | ||
{{description}} | ||
</span> | ||
{{/if}} | ||
</div> | ||
</div> | ||
</td> | ||
<td> | ||
<div class="rc-table-wrapper"> | ||
<div class="rc-table-info"> | ||
<button class="rc-tooltip game-center__invite-players js-invite" aria-label="Invite Friends"> | ||
{{> icon block="game-center__invite-players-icon" icon="plus"}} | ||
</button> | ||
</div> | ||
</div> | ||
</td> | ||
</tr> | ||
{{/each}} | ||
{{#if isLoading}} | ||
<tr> | ||
<td colspan="3" style="position: relative;">{{> loading}}</td> | ||
</tr> | ||
{{/if}} | ||
</tbody> | ||
{{/table}} | ||
<div class="rc-user-info-container flex-nav animated{{#unless showGame}} animated-hidden{{/unless}}"> | ||
{{#if showGame}} | ||
{{> GameContainer (gameContainerOptions) }} | ||
{{/if}} | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import toastr from 'toastr'; | ||
import { Template } from 'meteor/templating'; | ||
import { ReactiveVar } from 'meteor/reactive-var'; | ||
|
||
import { modal } from '../../../ui-utils/client'; | ||
import { APIClient, t } from '../../../utils/client'; | ||
|
||
const getExternalComponents = async (instance) => { | ||
try { | ||
const { externalComponents } = await APIClient.get('apps/externalComponents'); | ||
instance.games.set(externalComponents); | ||
} catch (e) { | ||
toastr.error((e.xhr.responseJSON && e.xhr.responseJSON.error) || e.message); | ||
} | ||
|
||
instance.isLoading.set(false); | ||
instance.ready.set(true); | ||
}; | ||
|
||
const openGame = (gameManifestInfo) => { | ||
const instance = Template.instance(); | ||
const { location = 'MODAL' } = gameManifestInfo; | ||
|
||
if (location === 'CONTEXTUAL_BAR') { | ||
instance.gameManifestInfo.set(gameManifestInfo); | ||
} else if (location === 'MODAL') { | ||
modal.open({ | ||
allowOutsideClick: false, | ||
data: { | ||
game: gameManifestInfo, | ||
}, | ||
template: 'GameContainer', | ||
type: 'rc-game', | ||
}); | ||
} | ||
}; | ||
|
||
Template.GameCenter.helpers({ | ||
isReady() { | ||
if (Template.instance().ready != null) { | ||
return Template.instance().ready.get(); | ||
} | ||
return false; | ||
}, | ||
games() { | ||
return Template.instance().games.get(); | ||
}, | ||
isLoading() { | ||
return Template.instance().isLoading.get(); | ||
}, | ||
onTableScroll() { | ||
const instance = Template.instance(); | ||
if (instance.loading || instance.end.get()) { | ||
return; | ||
} | ||
return function(currentTarget) { | ||
if (currentTarget.offsetHeight + currentTarget.scrollTop >= currentTarget.scrollHeight - 100) { | ||
return instance.page.set(instance.page.get() + 1); | ||
} | ||
}; | ||
}, | ||
showGame() { | ||
return Template.instance().gameManifestInfo.get(); | ||
}, | ||
gameContainerOptions() { | ||
const { gameManifestInfo, clearGameManifestInfo } = Template.instance(); | ||
|
||
return { | ||
game: gameManifestInfo.get(), | ||
showBackButton: true, | ||
clearGameManifestInfo, | ||
}; | ||
}, | ||
}); | ||
|
||
Template.GameCenter.onCreated(function() { | ||
this.ready = new ReactiveVar(false); | ||
this.games = new ReactiveVar([]); | ||
this.isLoading = new ReactiveVar(true); | ||
this.page = new ReactiveVar(0); | ||
this.end = new ReactiveVar(false); | ||
|
||
this.gameManifestInfo = new ReactiveVar(null); | ||
|
||
this.clearGameManifestInfo = () => { | ||
this.gameManifestInfo.set(null); | ||
}; | ||
|
||
getExternalComponents(this); | ||
}); | ||
|
||
Template.GameCenter.events({ | ||
'click .rc-game-center__game'() { | ||
const gameManifestInfo = this; | ||
|
||
openGame(gameManifestInfo); | ||
}, | ||
'click .js-invite'(event) { | ||
event.stopPropagation(); | ||
modal.open({ | ||
title: t('Invite You Friends to Join'), | ||
content: 'InvitePlayers', | ||
data: this, | ||
confirmOnEnter: false, | ||
showCancelButton: false, | ||
showConfirmButton: false, | ||
html: false, | ||
}); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<template name="GameContainer"> | ||
{{#if isContextualBar}} | ||
<header class="contextual-bar__header"> | ||
<div class="contextual-bar__header-data"> | ||
{{#if showBackButton}} | ||
<button | ||
class="rc-button rc-button--nude contextual-bar__header-back-btn js-back" | ||
title="{{_ 'Back_to_Game_Center'}}" | ||
> | ||
<i class="icon-angle-left"></i> | ||
</button> | ||
{{/if}} | ||
<img class="rc-table-avatar contextual-bar__header-icon" src="{{ game.icon }}"> | ||
<h1 class="contextual-bar__header-title">{{ game.name }}</h1> | ||
</div> | ||
<button class="contextual-bar__header-close js-close"> | ||
{{> icon block="contextual-bar__header-close-icon" icon="plus"}} | ||
</button> | ||
</header> | ||
{{/if}} | ||
|
||
{{#if isLoading}} | ||
{{> loading}} | ||
{{else}} | ||
<div class="rc-game__container {{#if isModal}} rc-game-modal__container {{/if}}"> | ||
<div class="rc-game__close">✖</div> | ||
<iframe class="rc-game__main {{#if isModal}} rc-game-modal__main {{/if}}" src="{{ game.url }}"></iframe> | ||
</div> | ||
{{/if}} | ||
</template> |
Oops, something went wrong.