Add "Join Discord" button

Based of the patreon supporter button.
Add a key "discordLink" to the config.json file and set it to your
Discord invite link.
This commit is contained in:
Stubenhocker1399
2019-09-07 22:22:00 +02:00
parent cba4e94da2
commit 9f30d98895
18 changed files with 186 additions and 6 deletions
+2 -1
View File
@@ -4,7 +4,7 @@ import { getUrl } from '../../../client/rev';
import { CREDITS, CONTRIBUTORS, Credit } from '../../../client/credits';
import { CHANGELOG } from '../../../generated/changelog';
import { SUPPORTER_REWARDS_LIST } from '../../../common/constants';
import { supporterLink, contactEmail } from '../../../client/data';
import { supporterLink, discordLink, contactEmail } from '../../../client/data';
function toCredit(credit: Credit) {
return {
@@ -27,5 +27,6 @@ export class About {
readonly changelog = CHANGELOG;
readonly rewards = SUPPORTER_REWARDS_LIST;
readonly patreonLink = supporterLink;
readonly discordLink = discordLink;
readonly contactEmail = contactEmail;
}
+4 -2
View File
@@ -6,9 +6,9 @@ import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
import { Subscription } from 'rxjs';
import { GameService } from '../services/gameService';
import { Model, Friend } from '../services/model';
import { version, host, contactEmail, supporterLink, twitterLink, copyrightName } from '../../client/data';
import { version, host, contactEmail, supporterLink, twitterLink, discordLink, copyrightName } from '../../client/data';
import { PonyTownGame } from '../../client/game';
import { faTwitter, faPatreon, faEnvelope, faCog, faHome, faGamepad, faInfoCircle, faHorseHead } from '../../client/icons';
import { faTwitter, faPatreon, faEnvelope, faCog, faHome, faGamepad, faInfoCircle, faHorseHead, faDiscord } from '../../client/icons';
import { InstallService } from '../services/installService';
import { OAuthProvider, Entity, FakeEntity, Pony } from '../../common/interfaces';
import { registerServiceWorker, isBrowserOutdated, checkIframeKey } from '../../client/clientUtils';
@@ -47,6 +47,7 @@ export class App implements OnInit, OnDestroy {
readonly emailIcon = faEnvelope;
readonly twitterIcon = faTwitter;
readonly patreonIcon = faPatreon;
readonly discordIcon = faDiscord;
readonly cogIcon = faCog;
readonly homeIcon = faHome;
readonly helpIcon = faGamepad;
@@ -54,6 +55,7 @@ export class App implements OnInit, OnDestroy {
readonly charactersIcon = faHorseHead;
readonly contactEmail = contactEmail;
readonly patreonLink = supporterLink;
readonly discordLink = discordLink;
readonly twitterLink = twitterLink;
readonly copyright = copyrightName;
private url = location.pathname;
@@ -14,6 +14,7 @@ page-loader(*ngIf="!playing")
h2.sr-only Character selection
.mx-auto(style="max-width: 400px;")
support-button.mb-3
discord-button.mb-3
install-button.mb-3
character-select(
[(error)]="error" [newButton]="true" [removeButton]="true" (change)="updateMuzzles()"
+2
View File
@@ -20,6 +20,8 @@ div(*ngIf="!playing")
div(*ngIf="!!account")
.form-group
support-button
.form-group
discord-button
.form-group(*ngIf="canInstall")
install-button
.form-group
@@ -0,0 +1,11 @@
a.btn.btn-lg.btn-outline-discord.btn-block.mb-2(
*ngIf="discordLink" (mouseenter)="pony.excite()" (mouseout)="pony.reset()" [href]="discordLink" target="_blank"
rel="noopener noreferrer")
| Join us on Discord!
svg.discord-logo(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300")
circle(fill="#2C2F33" cx="150" cy="150" r="150")
//path(xmlns="http://www.w3.org/2000/svg" d="M40 12s-4.586-3.59-10-4l-.488.977C34.406 10.176 36.652 11.89 39 14c-4.047-2.066-8.04-4-15-4-6.96 0-10.953 1.934-15 4 2.348-2.11 5.02-4.016 9.488-5.023L18 8c-5.68.535-10 4-10 4s-5.121 7.426-6 22c5.16 5.953 13 6 13 6l1.64-2.184C13.856 36.848 10.716 35.121 8 32c3.238 2.45 8.125 5 16 5s12.762-2.55 16-5c-2.715 3.121-5.855 4.848-8.64 5.816L33 40s7.84-.047 13-6c-.879-14.574-6-22-6-22zM17.5 30c-1.934 0-3.5-1.79-3.5-4s1.566-4 3.5-4 3.5 1.79 3.5 4-1.566 4-3.5 4zm13 0c-1.934 0-3.5-1.79-3.5-4s1.566-4 3.5-4 3.5 1.79 3.5 4-1.566 4-3.5 4z" fill="#8C9EFF" scale="3")
path(xmlns="http://www.w3.org/2000/svg" transform="translate(28,40)" fill="#7289DA" class="st0" d="M104.4 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1.1-6.1-4.5-11.1-10.2-11.1zM140.9 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1s-4.5-11.1-10.2-11.1z")
path(xmlns="http://www.w3.org/2000/svg" transform="translate(28,40)" fill="#7289DA" class="st0" d="M189.5 20h-134C44.2 20 35 29.2 35 40.6v135.2c0 11.4 9.2 20.6 20.5 20.6h113.4l-5.3-18.5 12.8 11.9 12.1 11.2 21.5 19V40.6c0-11.4-9.2-20.6-20.5-20.6zm-38.6 130.6s-3.6-4.3-6.6-8.1c13.1-3.7 18.1-11.9 18.1-11.9-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.5-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.7-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.3-1.8-1-2.8-1.7-2.8-1.7s4.8 8 17.5 11.8c-3 3.8-6.7 8.3-6.7 8.3-22.1-.7-30.5-15.2-30.5-15.2 0-32.2 14.4-58.3 14.4-58.3 14.4-10.8 28.1-10.5 28.1-10.5l1 1.2c-18 5.2-26.3 13.1-26.3 13.1s2.2-1.2 5.9-2.9c10.7-4.7 19.2-6 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.6 0 0-7.9-7.5-24.9-12.7l1.4-1.6s13.7-.3 28.1 10.5c0 0 14.4 26.1 14.4 58.3 0 0-8.5 14.5-30.6 15.2z")
.discord-pony
discord-pony(#pony [scale]="2")
@@ -0,0 +1,45 @@
@import '../../../../styles/partials/variables';
:host {
display: block;
}
.btn {
position: relative;
@media (max-width: 320px) {
white-space: normal;
}
}
.discord-logo {
position: absolute;
left: 8px;
top: 5px;
width: 30px;
height: 30px;
@media (max-width: 290px) {
display: none;
}
}
.discord-pony {
position: absolute;
right: 0;
bottom: 0;
height: 70px;
width: 100px;
overflow: hidden;
border-radius: $border-radius-lg - 2px;
> discord-pony {
position: absolute;
bottom: -95px;
left: -20px;
}
@media (max-width: 360px) {
display: none;
}
}
@@ -0,0 +1,13 @@
import { Component } from '@angular/core';
import { discordLink } from '../../../client/data';
@Component({
selector: 'discord-button',
templateUrl: 'discord-button.pug',
styleUrls: ['discord-button.scss'],
})
export class DiscordButton {
readonly discordLink = discordLink;
constructor() {
}
}
@@ -0,0 +1,3 @@
character-preview(
#characterPreview [pony]="pony" [state]="state" [noBackground]="true" [noShadow]="true"
[noOutline]="true" [scale]="scale" style="width: 180px; height: 180px; position: relative; top: -20px;")
@@ -0,0 +1,88 @@
import { Component, OnInit, OnDestroy, Input, ViewChild } from '@angular/core';
import { defaultExpression } from '../../../client/ponyUtils';
import { defaultPonyState } from '../../../client/ponyHelpers';
import { DISCORD_PONY } from '../../../common/constants';
import { Expression, Muzzle, HeadAnimation, Iris } from '../../../common/interfaces';
import { excite } from '../../../client/ponyAnimations';
import { FrameService, FrameLoop } from '../../services/frameService';
import { CharacterPreview } from '../character-preview/character-preview';
import { decompressPonyString } from '../../../common/compressPony';
const BLEP: Expression = {
...defaultExpression,
muzzle: Muzzle.Blep,
};
const EXCITED: Expression = {
...defaultExpression,
muzzle: Muzzle.SmileOpen,
};
const DERP: Expression = {
...defaultExpression,
muzzle: Muzzle.SmileOpen,
leftIris: Iris.Up,
};
@Component({
selector: 'discord-pony',
templateUrl: 'discord-pony.pug',
})
export class DiscordPony implements OnInit, OnDestroy {
@ViewChild('characterPreview', { static: true }) characterPreview!: CharacterPreview;
@Input() scale = 3;
pony = decompressPonyString(DISCORD_PONY);
state = defaultPonyState();
private expression?: Expression;
private headAnimation?: HeadAnimation;
private headTime = 0;
private loop: FrameLoop;
constructor(frameService: FrameService) {
this.loop = frameService.create(delta => this.tick(delta));
}
ngOnInit() {
this.loop.init();
}
ngOnDestroy() {
this.loop.destroy();
}
excite() {
this.headTime = 0;
this.headAnimation = excite;
this.expression = Math.random() < 0.2 ? DERP : EXCITED;
}
reset() {
this.expression = undefined;
}
private tick(delta: number) {
this.headTime += delta;
if (this.headAnimation) {
const frame = Math.floor(this.headTime * this.headAnimation.fps);
if (frame >= this.headAnimation.frames.length && !this.headAnimation.loop) {
this.headAnimation = undefined;
this.state.headAnimation = undefined;
this.state.headAnimationFrame = 0;
this.characterPreview.blink();
} else {
this.state.headAnimation = this.headAnimation;
this.state.headAnimationFrame = frame % this.headAnimation.frames.length;
}
} else {
this.state.headAnimation = undefined;
if (this.expression) {
if (Math.random() < 0.01) {
this.expression = undefined;
}
} else {
if (Math.random() < 0.005) {
this.expression = BLEP;
}
}
}
this.state.expression = this.expression;
}
}
@@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { supporterLink } from '../../../client/data';
import { supporterLink, discordLink } from '../../../client/data';
import { GENERAL_RULES } from '../../../common/constants';
@Component({
@@ -8,5 +8,6 @@ import { GENERAL_RULES } from '../../../common/constants';
})
export class PlayNotice {
readonly patreonLink = supporterLink;
readonly discordLink = discordLink;
readonly rules = GENERAL_RULES;
}
@@ -25,6 +25,8 @@ import { SpriteBox } from './sprite-box/sprite-box';
import { SpriteSelection } from './sprite-selection/sprite-selection';
import { SupportButton } from './support-button/support-button';
import { SupporterPony } from './supporter-pony/supporter-pony';
import { DiscordButton } from './discord-button/discord-button';
import { DiscordPony } from './discord-pony/discord-pony';
import { SetSelection, SetOutlineHidden } from './set-selection/set-selection';
import { CheckBox } from './check-box/check-box';
import { PortraitBox } from './portrait-box/portrait-box';
@@ -91,6 +93,8 @@ const declarations = [
SpriteSelection,
SupportButton,
SupporterPony,
DiscordButton,
DiscordPony,
SetSelection,
SetOutlineHidden,
CheckBox,