Skip to content

Commit

Permalink
feat: add qr code to invite dialog (#23)
Browse files Browse the repository at this point in the history
* feat: add qr code to invite dialog

* save qr code visibility
  • Loading branch information
philmtd authored Jan 20, 2023
1 parent ed82228 commit dfaa776
Show file tree
Hide file tree
Showing 11 changed files with 419 additions and 55 deletions.
358 changes: 313 additions & 45 deletions frontend/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@ngxs/logger-plugin": "3.7.6",
"@ngxs/storage-plugin": "3.7.6",
"@ngxs/store": "3.7.6",
"angularx-qrcode": "^15.0.1",
"css-fx-layout": "2.1.0",
"ngx-translate-messageformat-compiler": "^6.2.0",
"rxjs": "~7.8.0",
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import {FractionFilterPipe} from "./game/game/fraction-filter.pipe";
import {TranslateCompiler, TranslateLoader, TranslateModule, TranslateService} from "@ngx-translate/core";
import {TranslateHttpLoader} from "@ngx-translate/http-loader";
import {TranslateMessageFormatCompiler} from "ngx-translate-messageformat-compiler";
import {QRCodeModule} from "angularx-qrcode";
import {SettingsState} from "./store/settings/settings.state";

export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, '/assets/i18n/', '.json');
Expand Down Expand Up @@ -70,12 +72,13 @@ export function HttpLoaderFactory(http: HttpClient) {
FormsModule,
HttpClientModule,
NgxsModule.forRoot(appStates, {developmentMode: !environment.production}),
NgxsStoragePluginModule.forRoot({key: [UserState, ThemingState]}),
NgxsStoragePluginModule.forRoot({key: [UserState, ThemingState, SettingsState]}),
NgxsReduxDevtoolsPluginModule.forRoot(),
NgxsLoggerPluginModule.forRoot(),
MatIconModule,
MatMenuModule,
MatTooltipModule,
QRCodeModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
<div class="invite-players-dialog fx-layout-column fx-gap--2em">
<h2 mat-dialog-title>{{ 'components.invitePlayersDialog.title' | translate }}</h2>
<div mat-dialog-content>
<div class="fx-layout-column fx-align--x-center fx-align--center-x qr">
<qrcode [qrdata]="gameUrl"
*ngIf="(qrCodeVisible$ | async)"
elementType="svg"
[colorLight]="'00000000'"
cssClass="full-house-qr"
[margin]="0"
[width]="240">
</qrcode>
</div>
<mat-form-field appearance="fill">
<mat-label>{{ 'components.invitePlayersDialog.urlLabel' | translate }}</mat-label>
<input matInput #input autofocus readonly name="gameurl" [value]="gameUrl" />
<input matInput #input autofocus readonly name="gameurl" [value]="gameUrl"/>
</mat-form-field>
<button mat-flat-button color="primary" (click)="copyUrl()">{{ 'components.invitePlayersDialog.copyButton' | translate }}</button>
<button mat-flat-button color="primary" (click)="copyUrl()">
<div class="fx-layout-row fx-align--center-x fx-align--x-center fx-gap--8px">
<mat-icon svgIcon="content-copy"></mat-icon>
<span>{{ 'components.invitePlayersDialog.copyButton' | translate }}</span>
</div>
</button>

<button class="show-qr-button" tabindex="-1" mat-stroked-button color="primary" (click)="toggleQrCodeVisibility()">
<div class="fx-layout-row fx-align--center-x fx-align--x-center fx-gap--8px">
<mat-icon svgIcon="qr-code-scanner"></mat-icon>
<span>{{ 'components.invitePlayersDialog.showQrButton' | translate: {visible: (qrCodeVisible$ | async)} }}</span>
</div>
</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
.invite-players-dialog {
padding: 2em;

h1 {
h2 {
margin: 0;
}

mat-form-field, button {
width: 100%;
}

.show-qr-button {
margin-top: 1em;
}

.qr {
margin-bottom: 1em;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@use '@angular/material' as mat;
@import "src/styles/mixins";

@mixin invite-players-dialog-theme($theme) {
$primary: map-get($theme, primary);
.full-house-qr {
svg {
path {
stroke: mat.get-color-from-palette($primary, 500);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import {AfterContentInit, AfterViewInit, ChangeDetectorRef, Component, ElementRef, ViewChild} from "@angular/core";
import {AfterViewInit, ChangeDetectorRef, Component, ElementRef, ViewChild} from "@angular/core";
import {MatDialogRef} from "@angular/material/dialog";
import {Clipboard} from "@angular/cdk/clipboard";
import {Select, Store} from "@ngxs/store";
import {Observable} from "rxjs";
import {SettingsState, ToggleQrCodeVisibility} from "../../store/settings/settings.state";

@Component({
selector: 'invite-players-dialog-component',
templateUrl: 'invite-players-dialog.component.html',
styleUrls: ['./invite-players-dialog.component.scss']
styleUrls: ['./invite-players-dialog.component.scss'],
})
export class InvitePlayersDialogComponent implements AfterViewInit {

public gameUrl: string;

@Select(SettingsState.isInviteQrCodeVisible) qrCodeVisible$: Observable<boolean>;
@ViewChild('input') input: ElementRef<HTMLInputElement>;

constructor(private dialogRef: MatDialogRef<InvitePlayersDialogComponent>,
private clipboard: Clipboard,
private cd: ChangeDetectorRef) {
private cd: ChangeDetectorRef,
private store: Store) {
this.gameUrl = window.location.toString();
}

Expand All @@ -29,4 +33,7 @@ export class InvitePlayersDialogComponent implements AfterViewInit {
this.cd.detectChanges();
}

toggleQrCodeVisibility() {
this.store.dispatch(new ToggleQrCodeVisibility());
}
}
4 changes: 3 additions & 1 deletion frontend/src/app/store/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {UserState} from "./user/user.state";
import {ThemingState} from "./theming/theming.state";
import {SettingsState} from "./settings/settings.state";

export const appStates = [
ThemingState,
UserState
UserState,
SettingsState
];
37 changes: 37 additions & 0 deletions frontend/src/app/store/settings/settings.state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {Action, NgxsOnInit, Selector, State, StateContext, Store} from '@ngxs/store';
import {Injectable} from '@angular/core';
import {filter, first} from 'rxjs/operators';

export interface SettingsStateModel {
inviteQrCodeVisible: boolean;
}

const defaultState: SettingsStateModel = {
inviteQrCodeVisible: false
};

export class ToggleQrCodeVisibility {
static readonly type = '[Settings] Toggle QR code visibility';

}

@State({
name: 'ppSettings',
defaults: defaultState
})
@Injectable()
export class SettingsState {

@Selector()
static isInviteQrCodeVisible(state: SettingsStateModel): boolean {
return state.inviteQrCodeVisible;
}

@Action(ToggleQrCodeVisibility)
toggleQrCodeVisibility(ctx: StateContext<SettingsStateModel>) {
ctx.patchState({
inviteQrCodeVisible: !ctx.getState().inviteQrCodeVisible
});
}

}
3 changes: 2 additions & 1 deletion frontend/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"invitePlayersDialog": {
"title": "Invite players",
"urlLabel": "URL",
"copyButton": "Copy game link"
"copyButton": "Copy game link",
"showQrButton": "{visible, select, true{Hide} other{Show}} QR code"
},
"themeSwitcher": {
"auto": "Auto",
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/styles/component-themes.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
@import "src/app/components/invite-players-dialog/invite-players-dialog.component.theme";
@import "src/app/components/theme-switcher/theme-switcher.component.theme";
@import "src/app/game/game/game.component.theme";
@import "src/app/game/participant/participant.component.theme";

@mixin component-themes($theme) {
@include invite-players-dialog-theme($theme);
@include theme-switcher-component-theme($theme);
@include game-component-theme($theme);
@include participant-component-theme($theme);
Expand Down

0 comments on commit dfaa776

Please sign in to comment.