Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions app/components/lobbyside-staff-widget/index.hbs

This file was deleted.

64 changes: 0 additions & 64 deletions app/components/lobbyside-staff-widget/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion app/components/lobbyside-widget/index.hbs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{{#if this.shouldShow}}
<div {{did-insert this.insertScript}} {{will-destroy this.removeScript}}></div>
<div {{did-insert this.insertScript}} {{did-update this.syncVisitorData this.authenticator.currentUserId}} {{will-destroy this.removeScript}}></div>
{{/if}}
58 changes: 41 additions & 17 deletions app/components/lobbyside-widget/index.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,81 @@
import Component from '@glimmer/component';
import { service } from '@ember/service';
import { action } from '@ember/object';
import { userIsStaffOrAllowlisted } from 'codecrafters-frontend/utils/staff-allowlist';
import type AuthenticatorService from 'codecrafters-frontend/services/authenticator';

const LOBBYSIDE_SCRIPT_ID = 'lobbyside-widget-script';
declare global {
interface Window {
Lobbyside?: {
setVisitor(visitor: { email: string; name: string; github: string }): void;
};
}
}

export type LobbysideAudience = 'everyone' | 'staff';

export interface LobbysideWidgetSignature {
Element: HTMLDivElement;
Args: {
widgetId: string;
audience?: LobbysideAudience;
};
}

export default class LobbysideWidgetComponent extends Component {
export default class LobbysideWidgetComponent extends Component<LobbysideWidgetSignature> {
@service declare authenticator: AuthenticatorService;

get scriptId(): string {
return `lobbyside-widget-${this.args.widgetId}`;
}

get shouldShow(): boolean {
if ((this.args.audience ?? 'everyone') === 'staff') {
return userIsStaffOrAllowlisted(this.authenticator.currentUser);
}

return true;
}

@action
insertScript(): void {
if (document.getElementById(LOBBYSIDE_SCRIPT_ID)) {
if (document.getElementById(this.scriptId)) {
this.syncVisitorData();

return;
}

const script = document.createElement('script');
script.id = LOBBYSIDE_SCRIPT_ID;
script.id = this.scriptId;
script.src = 'https://lobbyside.com/widget.js';
script.dataset['companyId'] = 'f6948b5a-eac2-4f92-8fce-54d4fb3bdaa4';
script.dataset['widgetId'] = this.args.widgetId;
script.onload = () => this.syncVisitorData();
document.body.appendChild(script);
}

@action
removeScript(): void {
const script = document.getElementById(LOBBYSIDE_SCRIPT_ID);

if (script) {
script.remove();
}
document.getElementById(this.scriptId)?.remove();
}

private syncVisitorData(): void {
@action
syncVisitorData(): void {
const user = this.authenticator.currentUser;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (!user || !(window as any)['Lobbyside']) {
if (!user || !window.Lobbyside) {
return;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const lobbyside = (window as any).Lobbyside;

lobbyside.setVisitor({
window.Lobbyside.setVisitor({
email: user.primaryEmailAddress || '',
name: user.name || user.githubName || '',
github: user.githubUsername || '',
});
}
}

declare module '@glint/environment-ember-loose/registry' {
export default interface Registry {
LobbysideWidget: typeof LobbysideWidgetComponent;
}
}
7 changes: 3 additions & 4 deletions app/services/beacon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@ import Service, { service } from '@ember/service';
import type RouterService from '@ember/routing/router-service';
import type RouteInfo from '@ember/routing/route-info';
import RouteInfoMetadata, { HelpscoutBeaconVisibility } from 'codecrafters-frontend/utils/route-info-metadata';
import { userIsStaffOrAllowlisted } from 'codecrafters-frontend/utils/staff-allowlist';
import type AuthenticatorService from 'codecrafters-frontend/services/authenticator';

export default class HelpscoutBeaconService extends Service {
@service declare authenticator: AuthenticatorService;
@service declare router: RouterService;

get shouldShowBeacon(): boolean {
// Staff users and specific users see the Lobbyside widget instead of HelpScout
const user = this.authenticator.currentUser;

if (user?.isStaff || user?.username === 'vishaag' || user?.username === 'dronaxis') {
// Staff and allowlisted users see the Lobbyside widget instead of HelpScout
if (userIsStaffOrAllowlisted(this.authenticator.currentUser)) {
return false;
}

Expand Down
5 changes: 3 additions & 2 deletions app/templates/application.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
<HelpscoutBeacon />
{{/if}}

<LobbysideWidget />
<LobbysideStaffWidget />
<LobbysideWidget @widgetId="f6948b5a-eac2-4f92-8fce-54d4fb3bdaa4" />
<LobbysideWidget @widgetId="b0d7150e-77e2-431c-a57c-765e080d9c72" />
<LobbysideWidget @widgetId="665ad94a-a863-4d0e-98e5-ff3eeac3f264" @audience="staff" />

{{! Enable this to debug ember-animated animations }}
{{! <AnimatedTools /> }}
Expand Down
11 changes: 11 additions & 0 deletions app/utils/staff-allowlist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type UserModel from 'codecrafters-frontend/models/user';

export const STAFF_ALLOWLIST_USERNAMES = ['vishaag', 'dronaxis'];

export function userIsStaffOrAllowlisted(user: UserModel | null | undefined): boolean {
if (!user) {
return false;
}

return user.isStaff || STAFF_ALLOWLIST_USERNAMES.includes(user.username);
}
Loading