JS frontend stuff
Move old ember frontend to properly named folder Add vue based new frontend
This commit is contained in:
parent
8947d97825
commit
88398334fe
254 changed files with 837 additions and 0 deletions
12
frontend-old-ember/app/app.ts
Normal file
12
frontend-old-ember/app/app.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import Application from '@ember/application';
|
||||
import Resolver from 'ember-resolver';
|
||||
import loadInitializers from 'ember-load-initializers';
|
||||
import config from 'frontend-reactive/config/environment';
|
||||
|
||||
export default class App extends Application {
|
||||
modulePrefix = config.modulePrefix;
|
||||
podModulePrefix = config.podModulePrefix;
|
||||
Resolver = Resolver;
|
||||
}
|
||||
|
||||
loadInitializers(App, config.modulePrefix);
|
0
frontend-old-ember/app/components/.gitkeep
Normal file
0
frontend-old-ember/app/components/.gitkeep
Normal file
1
frontend-old-ember/app/components/account/full.hbs
Normal file
1
frontend-old-ember/app/components/account/full.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
18
frontend-old-ember/app/components/account/header.hbs
Normal file
18
frontend-old-ember/app/components/account/header.hbs
Normal file
|
@ -0,0 +1,18 @@
|
|||
<div class="account-header">
|
||||
<Account::Header::Profilepicture @meta={{@data.icon}} />
|
||||
<div class="account-header-">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="account-header">
|
||||
<Account::Header::Profilepicture @meta={{@data.icon}} />
|
||||
<div class="account-header-text">
|
||||
<Note::Formatter
|
||||
@classes="note-user-displayname"
|
||||
@content={{@data.displayname}}
|
||||
@server={{@data.originServer}}
|
||||
/>
|
||||
<p class="note-user-displayname"></p>
|
||||
<p class="note-user-handle">{{@data.originServer.id}}</p>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
<img class="profile-picture" src="{{@meta.url}}" alt="{{@meta.altText}}" />
|
3
frontend-old-ember/app/components/account/overview.hbs
Normal file
3
frontend-old-ember/app/components/account/overview.hbs
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class="profile-overview">
|
||||
<Account::Header @data={{@data}} />
|
||||
</div>
|
18
frontend-old-ember/app/components/auth.hbs
Normal file
18
frontend-old-ember/app/components/auth.hbs
Normal file
|
@ -0,0 +1,18 @@
|
|||
<div class="auth-wrapper">
|
||||
<div class="auth-username-wrapper">
|
||||
<label>
|
||||
Username
|
||||
<Input
|
||||
@type="text"
|
||||
@value={{this.username}}
|
||||
placeholder="Username"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div type="button" class="auth-button-login" {{on "click" this.startLogin}}>
|
||||
Login
|
||||
</div>
|
||||
<div type="button" class="auth-button-register" {{on "click" this.startRegistration}}>
|
||||
Register
|
||||
</div>
|
||||
</div>
|
50
frontend-old-ember/app/components/auth.ts
Normal file
50
frontend-old-ember/app/components/auth.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { action } from '@ember/object';
|
||||
import { service } from '@ember/service';
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import '@simplewebauthn/browser';
|
||||
import {
|
||||
startAuthentication,
|
||||
startRegistration,
|
||||
} from '@simplewebauthn/browser';
|
||||
import type AuthService from 'frontend-reactive/services/auth';
|
||||
|
||||
export interface AuthSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class Auth extends Component<AuthSignature> {
|
||||
@tracked username: string = '';
|
||||
@tracked error: string | undefined;
|
||||
//@tracked isLogin = true;
|
||||
@service declare auth: AuthService;
|
||||
|
||||
@action async startLogin() {
|
||||
try {
|
||||
// TODO: Check if account exists and is alowed to login
|
||||
this.auth.startLogin(this.username);
|
||||
} catch (error: any) {
|
||||
this.error = 'Error: ' + error.message;
|
||||
}
|
||||
}
|
||||
|
||||
@action async startRegistration() {
|
||||
try {
|
||||
// TODO: Check if handle is already taken
|
||||
await this.auth.startRegistration(this.username);
|
||||
// After registration, log in immediately to obtain a valid session token
|
||||
// for the "post" registration data, such as email
|
||||
await this.auth.startLogin(this.username);
|
||||
// And after login,
|
||||
} catch (error: any) {
|
||||
this.error = 'Error: ' + error.message;
|
||||
}
|
||||
}
|
||||
}
|
12
frontend-old-ember/app/components/auth/login.hbs
Normal file
12
frontend-old-ember/app/components/auth/login.hbs
Normal file
|
@ -0,0 +1,12 @@
|
|||
<div class="login-wrapper">
|
||||
<label>
|
||||
<Input
|
||||
@type="text"
|
||||
@value={{this.username}}
|
||||
placeholder="Username"
|
||||
/>
|
||||
</label>
|
||||
<div type="button" class="login-start-button" {{on "click" this.onLoginStart}}>
|
||||
Login
|
||||
</div>
|
||||
</div>
|
24
frontend-old-ember/app/components/auth/login.ts
Normal file
24
frontend-old-ember/app/components/auth/login.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { action } from '@ember/object';
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
|
||||
export interface AuthLoginSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class AuthLogin extends Component<AuthLoginSignature> {
|
||||
@tracked username = '';
|
||||
|
||||
@action onLoginStart() {
|
||||
console.log('Starting login for username ' + this.username);
|
||||
// Check if username is approved for login
|
||||
// If it is, continue with login
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<div class="registration-form">
|
||||
<h1 class="registration-form-username">username: {{this.args.username}}</h1>
|
||||
<div class="registration-form-name-mail-wrapper">
|
||||
<div class="registration-form-displayname-wrapper">
|
||||
<label>
|
||||
Displayname
|
||||
<Input
|
||||
@type="text"
|
||||
@value={{this.displayname}}
|
||||
placeholder="Displayname"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<Util::MailEntry
|
||||
@wrapper-classes="registration-form-mail-wrapper"
|
||||
@input-classes="registration-form-mail-input"
|
||||
@data={{this.mail}}
|
||||
/>
|
||||
</div>
|
||||
<div class="registration-form-description-wrapper">
|
||||
{{! TODO: Split into entry form on the left and live preview on the right }}
|
||||
<label for="registration-description">
|
||||
Description
|
||||
</label>
|
||||
<Textarea
|
||||
id="registration-description"
|
||||
@value={{this.description}}
|
||||
placeholder="Account description"
|
||||
/>
|
||||
</div>
|
||||
<fieldset class="registration-form-gender-wrapper">
|
||||
<legend class="registration-form-gender-info">Add your preferred pronouns</legend>
|
||||
<Util::StringArray
|
||||
@list={{this.gender}}
|
||||
@onNewElement={{this.genderAddedHandler}}
|
||||
@onDeleteElement={{this.genderRemovedHandler}}
|
||||
@wrapper-classes=""
|
||||
@element-wrapper-classes=""
|
||||
@element-classes=""
|
||||
@remove-element-classes=""
|
||||
@add-element-classes=""
|
||||
/>
|
||||
</fieldset>
|
||||
<fieldset class="register-form-being-wrapper">
|
||||
<legend class="registration-form-being-info">Select the type of being you are. Multiselect is possible</legend>
|
||||
<Util::Multiselect
|
||||
@elements={{this.beingTypes}}
|
||||
@wrapper-class=""
|
||||
@label-class=""
|
||||
@input-classes=""
|
||||
/>
|
||||
</fieldset>
|
||||
<fieldset class="register-form-default-post-mode-wrapper">
|
||||
<legend class="registration-form-default-post-mode-info">Select the default mode for your posts</legend>
|
||||
<Util::OneOfArray
|
||||
@elements={{array "Public" "Local" "Followers" "Direct"}}
|
||||
@selected={{this.defaultpostmode}}
|
||||
@name="default-post-mode"
|
||||
@required={{true}}
|
||||
/>
|
||||
</fieldset>
|
||||
<div class="register-form-follow-approval-wrapper">
|
||||
<label>
|
||||
Require approval for follow requests
|
||||
<Input
|
||||
@type="checkbox"
|
||||
name="Follow approval"
|
||||
@checked={{this.args.followapproval}}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="register-form-indexable-wrapper">
|
||||
<label>
|
||||
Whether the account is indexable
|
||||
<Input @type="checkbox" name="Indexable" @checked={{this.indexable}} />
|
||||
</label>
|
||||
</div>
|
||||
<fieldset class="register-form-custom-fields-wrapper">
|
||||
<legend>Custom fields</legend>
|
||||
<Util::MapEdit @list={{this.customProperties}} />
|
||||
</fieldset>
|
||||
{{! TODO: Icon, Background, Banner, Bluesky toggle }}
|
||||
</div>
|
|
@ -0,0 +1,76 @@
|
|||
import { action } from '@ember/object';
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import isValidMail from 'frontend-reactive/helpers/is-valid-mail';
|
||||
|
||||
export interface AuthPostRegistrationFormSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {
|
||||
username: string;
|
||||
};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class AuthPostRegistrationForm extends Component<AuthPostRegistrationFormSignature> {
|
||||
@tracked displayname: string = this.args.username;
|
||||
@tracked description: string = '';
|
||||
@tracked gender: Array<{ value: string }> = [];
|
||||
@tracked beingTypes: Array<{
|
||||
name: string;
|
||||
checked: boolean;
|
||||
description: string;
|
||||
}> = [
|
||||
{
|
||||
name: 'Human',
|
||||
description: 'Human',
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
name: 'Cat',
|
||||
description: 'Cat',
|
||||
checked: false,
|
||||
},
|
||||
{
|
||||
name: 'Fox',
|
||||
description: 'Fox',
|
||||
checked: false,
|
||||
},
|
||||
{
|
||||
name: 'Dog',
|
||||
description: 'Dog',
|
||||
checked: false,
|
||||
},
|
||||
{
|
||||
name: 'Robot',
|
||||
description: 'Robot',
|
||||
checked: false,
|
||||
},
|
||||
{
|
||||
name: 'Doll',
|
||||
description: 'Doll',
|
||||
checked: false,
|
||||
},
|
||||
];
|
||||
@tracked defaultpostmode: string = 'Public';
|
||||
@tracked followapproval: boolean = false;
|
||||
@tracked customProperties: Array<{ key: string; value: string }> = [];
|
||||
@tracked indexable: boolean = true;
|
||||
@tracked mail = { mail: '', valid: false };
|
||||
@tracked enableBlueskyIntegration = false;
|
||||
|
||||
genderAddedHandler(newIndex: number) {
|
||||
console.log('gender added');
|
||||
}
|
||||
genderRemovedHandler(removedIndex: number) {
|
||||
console.log('gender removed');
|
||||
}
|
||||
|
||||
@action test() {
|
||||
console.log(this.mail);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
14
frontend-old-ember/app/components/auth/register-start.ts
Normal file
14
frontend-old-ember/app/components/auth/register-start.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import Component from '@glimmer/component';
|
||||
|
||||
export interface AuthRegisterStartSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class AuthRegisterStart extends Component<AuthRegisterStartSignature> {}
|
|
@ -0,0 +1,5 @@
|
|||
<div class="global-sidebar-general">
|
||||
<div class="global-sidebar-general-feed">
|
||||
|
||||
</div>
|
||||
</div>
|
18
frontend-old-ember/app/components/note.hbs
Normal file
18
frontend-old-ember/app/components/note.hbs
Normal file
|
@ -0,0 +1,18 @@
|
|||
<div class="note">
|
||||
{{!-- TODO: figure out how to make the entire note clickable for opening with something like {{on "click" (fn this.openFullView)}} --}}
|
||||
<Note::UserHeader
|
||||
@displayname="{{@note.displayname}}"
|
||||
@handle="@{{@note.username}}@{{@note.server}}"
|
||||
@server="{{@note.servertype}}"
|
||||
/>
|
||||
<Note::Content @content="{{@note.content}}" />
|
||||
<div class="note-timestamps-container">
|
||||
{{#if @note.editedAt}}
|
||||
<p class="note-timestamp" id="note-edited-timestamp">Edited: {{moment-format @note.editedAt "MMM DD, YYYY H:mm"}}</p>
|
||||
{{/if}}
|
||||
<p class="note-timestamp" id="note-created-timestamp">Posted: {{moment-format @note.createdAt "MMM DD, YYYY H:mm"}}</p>
|
||||
</div>
|
||||
{{!--<div class="separator-horizontal" />--}}
|
||||
{{!-- TODO: Hardcoded values here, make them dynamic --}}
|
||||
<Note::Interactions @boostCount="25" @totalLikeCount="300" @hasBoosted="true" @hasReacted="false" />
|
||||
</div>
|
34
frontend-old-ember/app/components/note.ts
Normal file
34
frontend-old-ember/app/components/note.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { action } from '@ember/object';
|
||||
import Component from '@glimmer/component';
|
||||
|
||||
export interface NoteSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {
|
||||
isInTimeline: boolean;
|
||||
note: {
|
||||
content: string;
|
||||
server: string;
|
||||
username: string;
|
||||
displayname: string;
|
||||
createdAt: number;
|
||||
editedAt?: number;
|
||||
};
|
||||
};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class Note extends Component<NoteSignature> {
|
||||
@action
|
||||
openFullView() {
|
||||
if (this.args.isInTimeline) {
|
||||
alert("Would have opened note's own view");
|
||||
} else {
|
||||
console.log("Alread in note specific view, can't open it again");
|
||||
}
|
||||
}
|
||||
}
|
19
frontend-old-ember/app/components/note/content.hbs
Normal file
19
frontend-old-ember/app/components/note/content.hbs
Normal file
|
@ -0,0 +1,19 @@
|
|||
<div class="note-content">
|
||||
<p class="note-content-text">{{this.visibleContent}}</p>
|
||||
{{#if this.canExpand}}
|
||||
{{#if this.collapsed}}
|
||||
<div
|
||||
type="button"
|
||||
class="note-content-toggle"
|
||||
{{on "click" this.expand}}
|
||||
>{{t "note.expand"}}</div>
|
||||
{{else}}
|
||||
<div
|
||||
type="button"
|
||||
class="note-content-toggle"
|
||||
{{on "click" this.collapse}}
|
||||
>{{t "note.collapse"}}</div>
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
</div>
|
58
frontend-old-ember/app/components/note/content.ts
Normal file
58
frontend-old-ember/app/components/note/content.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { action } from '@ember/object';
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
|
||||
export interface NoteContentSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {
|
||||
content: string;
|
||||
preFormatted: boolean;
|
||||
};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class NoteContent extends Component<NoteContentSignature> {
|
||||
// Default to collapsed content
|
||||
@tracked visibleContent =
|
||||
this.args.content.length > 200 ? this.cutDownContent() : this.args.content;
|
||||
|
||||
@tracked collapsed = true;
|
||||
@tracked canExpand = this.args.content.length > 200;
|
||||
|
||||
@action
|
||||
expand() {
|
||||
this.visibleContent = this.args.content;
|
||||
this.collapsed = false;
|
||||
}
|
||||
|
||||
@action
|
||||
collapse() {
|
||||
this.visibleContent =
|
||||
this.args.content.length > 200
|
||||
? this.cutDownContent()
|
||||
: this.args.content;
|
||||
this.collapsed = true;
|
||||
}
|
||||
|
||||
cutDownContent(): string {
|
||||
if (this.args.content.length > 200) {
|
||||
const words = this.args.content.split(' ');
|
||||
let outString = '';
|
||||
for (const word of words) {
|
||||
if (outString.length > 200) {
|
||||
return outString + '...';
|
||||
}
|
||||
outString += word + ' ';
|
||||
}
|
||||
} else {
|
||||
return this.args.content;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
46
frontend-old-ember/app/components/note/interactions.hbs
Normal file
46
frontend-old-ember/app/components/note/interactions.hbs
Normal file
|
@ -0,0 +1,46 @@
|
|||
{{!-- TODO: Add translations --}}
|
||||
<div class="resource-preload">
|
||||
</div>
|
||||
<div class="note-interactions-wrapper">
|
||||
<div type="button" class="note-interactions-interaction-button" {{on "click" this.toggleBoost}}>
|
||||
{{#if this.hasBoosted}}
|
||||
<Svgs::ReloadOutline @class="note-interactions-interaction-icon"/>
|
||||
{{else}}
|
||||
<Svgs::ReloadColoured @class="note-interactions-interaction-icon"/>
|
||||
{{/if}}
|
||||
<p class="note-interactions-interaction-counter noselect">{{this.args.boostCount}}</p>
|
||||
<EmberTooltip @text="Boost this note" @side="top-start"/>
|
||||
</div>
|
||||
<div class="note-interactions-interaction-button">
|
||||
<div
|
||||
type="button"
|
||||
class="note-interactions-interactions-button-like"
|
||||
aria-label="Like or unlike" {{on "click" this.toggleDefaultLike}}
|
||||
>
|
||||
{{#if this.hasReacted}}
|
||||
<Svgs::HeartOutline @class="note-interactions-interaction-icon"/>
|
||||
{{else}}
|
||||
<Svgs::HeartFilled @class="note-interactions-interaction-icon"/>
|
||||
{{/if}}
|
||||
<p class="note-interactions-interaction-counter noselect">{{this.args.totalLikeCount}}</p>
|
||||
<EmberTooltip @text="Like this note"/>
|
||||
</div>
|
||||
<div
|
||||
class="note-interactions-interactions-button-custom"
|
||||
aria-label="Send a custom reaction" type="button"
|
||||
{{on "click" this.openCustomReactionSelector}}
|
||||
>
|
||||
<Svgs::PlusBlack @class="note-interactions-interaction-icon"/>
|
||||
<EmberTooltip @text="Send a custom reaction"/>
|
||||
</div>
|
||||
<div
|
||||
class="note-interactions-interactions-button-custom"
|
||||
type="button"
|
||||
aria-label="Expand existing reactions"
|
||||
{{on "click" this.openAllReactions}}
|
||||
>
|
||||
<Svgs::ArrowDownBlack @class="note-interactions-interaction-icon"/>
|
||||
<EmberTooltip @text="Expand reactions"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
53
frontend-old-ember/app/components/note/interactions.ts
Normal file
53
frontend-old-ember/app/components/note/interactions.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { action } from '@ember/object';
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import isLandscape from 'frontend-reactive/helpers/isLandscape';
|
||||
|
||||
export interface NoteInteractionsSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {
|
||||
boostCount: number;
|
||||
totalLikeCount: number;
|
||||
reactions: {
|
||||
[key: string]: number;
|
||||
};
|
||||
hasBoosted: boolean;
|
||||
hasReacted: boolean;
|
||||
};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class NoteInteractions extends Component<NoteInteractionsSignature> {
|
||||
@tracked hasBoosted = this.args.hasBoosted;
|
||||
@tracked hasReacted = this.args.hasReacted;
|
||||
@tracked expandReactions = false;
|
||||
|
||||
@action
|
||||
toggleBoost() {
|
||||
this.hasBoosted = !this.hasBoosted;
|
||||
console.log('boosted', this.hasBoosted);
|
||||
}
|
||||
|
||||
@action
|
||||
toggleDefaultLike() {
|
||||
this.hasReacted = !this.hasReacted;
|
||||
console.log('reacted', this.hasReacted);
|
||||
}
|
||||
|
||||
@action
|
||||
openCustomReactionSelector() {
|
||||
this.hasReacted = !this.hasReacted;
|
||||
console.log('sent custom reaction', this.hasReacted);
|
||||
}
|
||||
|
||||
@action
|
||||
openAllReactions() {
|
||||
console.log('Toggle all reactions overview');
|
||||
this.expandReactions = !this.expandReactions;
|
||||
}
|
||||
}
|
11
frontend-old-ember/app/components/note/user-header.hbs
Normal file
11
frontend-old-ember/app/components/note/user-header.hbs
Normal file
|
@ -0,0 +1,11 @@
|
|||
<div class="note-user-header">
|
||||
<div class="note-user-pfp">
|
||||
<p>Pfp</p>
|
||||
</div>
|
||||
<div class="note-user-name-and-handle">
|
||||
<p class="note-user-displayname">{{@displayname}}:{{@server}}</p>
|
||||
<!--<Util::Formatter @classes="note-user-displayname" @content={{@displayname}} @server={{@server}}/>-->
|
||||
<p class="note-user-displayname"></p>
|
||||
<p class="note-user-handle">{{@handle}}</p>
|
||||
</div>
|
||||
</div>
|
1
frontend-old-ember/app/components/page.hbs
Normal file
1
frontend-old-ember/app/components/page.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
1
frontend-old-ember/app/components/page/header.hbs
Normal file
1
frontend-old-ember/app/components/page/header.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
1
frontend-old-ember/app/components/page/left-sidebar.hbs
Normal file
1
frontend-old-ember/app/components/page/left-sidebar.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
|
@ -0,0 +1,9 @@
|
|||
{{!--Source: https://www.iconpacks.net/free-icon/arrow-down-3101.html--}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve" class="{{@class}}">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path class="svg-black-white" d="M 90 24.25 c 0 -0.896 -0.342 -1.792 -1.025 -2.475 c -1.366 -1.367 -3.583 -1.367 -4.949 0 L 45 60.8 L 5.975 21.775 c -1.367 -1.367 -3.583 -1.367 -4.95 0 c -1.366 1.367 -1.366 3.583 0 4.95 l 41.5 41.5 c 1.366 1.367 3.583 1.367 4.949 0 l 41.5 -41.5 C 89.658 26.042 90 25.146 90 24.25 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
|
@ -0,0 +1,9 @@
|
|||
{{!--Source: https://www.iconpacks.net/free-icon/arrow-right-3098.html--}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve" class="{{@class}}">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path class="svg-black-white" d="M 24.25 90 c -0.896 0 -1.792 -0.342 -2.475 -1.025 c -1.367 -1.366 -1.367 -3.583 0 -4.949 L 60.8 45 L 21.775 5.975 c -1.367 -1.367 -1.367 -3.583 0 -4.95 c 1.367 -1.366 3.583 -1.366 4.95 0 l 41.5 41.5 c 1.367 1.366 1.367 3.583 0 4.949 l -41.5 41.5 C 26.042 89.658 25.146 90 24.25 90 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
14
frontend-old-ember/app/components/svgs/heart-filled.hbs
Normal file
14
frontend-old-ember/app/components/svgs/heart-filled.hbs
Normal file
|
@ -0,0 +1,14 @@
|
|||
{{!--Source: https://www.iconpacks.net/free-icon/rainbow-heart-4025.html--}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve" class="{{@class}}">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path d="M 22.353 72.146 c 6.131 5.349 13.628 10.42 22.647 14.93 c 9.019 -4.509 16.516 -9.58 22.647 -14.93 C 51.886 71.433 38.115 71.433 22.353 72.146 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(162,0,247); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path d="M 9.921 58.519 c 3.683 5.228 8.467 10.41 14.444 15.327 h 41.27 c 5.977 -4.917 10.761 -10.099 14.444 -15.327 C 54.42 56.482 35.58 56.482 9.921 58.519 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(1,104,248); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path d="M 2.868 45.313 c 1.777 4.764 4.411 9.652 7.991 14.49 h 68.283 c 3.58 -4.838 6.214 -9.726 7.991 -14.49 C 55.317 43.478 34.683 43.478 2.868 45.313 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(3,143,0); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path d="M 0.011 31.231 c 0.114 4.567 1.084 9.479 3.021 14.53 h 83.936 c 1.937 -5.051 2.907 -9.963 3.021 -14.53 C 55.571 27.636 34.429 27.636 0.011 31.231 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(248,245,1); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path d="M 3.063 16.796 c -2.176 4.208 -3.251 9.31 -3.037 14.923 h 89.947 c 0.214 -5.613 -0.861 -10.715 -3.037 -14.923 C 55.299 13.301 34.701 13.301 3.063 16.796 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(248,146,0); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path d="M 2.622 17.677 h 84.756 C 81.379 4.833 65.599 -0.363 45 12.219 C 24.401 -0.363 8.621 4.833 2.622 17.677 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(247,0,0); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
10
frontend-old-ember/app/components/svgs/heart-outline.hbs
Normal file
10
frontend-old-ember/app/components/svgs/heart-outline.hbs
Normal file
|
@ -0,0 +1,10 @@
|
|||
{{!--Source: https://www.iconpacks.net/free-icon/heart-2930.html--}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve" class="{{@class}}">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path class="svg-black-white" d="M 45 86.215 c -0.307 0 -0.613 -0.07 -0.895 -0.211 C 12.38 70.141 0.53 47.275 0.019 31.165 C -0.32 20.477 4.083 11.415 11.799 6.924 C 20.661 1.766 32.416 2.997 45 10.373 c 12.585 -7.375 24.338 -8.605 33.201 -3.449 c 7.716 4.491 12.119 13.553 11.78 24.241 c -0.511 16.11 -12.361 38.976 -44.087 54.839 C 45.613 86.145 45.307 86.215 45 86.215 z M 23.93 7.787 c -3.729 0 -7.139 0.86 -10.119 2.594 c -6.521 3.795 -10.09 11.324 -9.794 20.657 C 4.486 45.847 15.519 66.926 45 81.975 c 29.481 -15.049 40.514 -36.128 40.983 -50.937 c 0.296 -9.333 -3.273 -16.862 -9.795 -20.657 c -7.777 -4.528 -18.483 -3.095 -30.146 4.028 c -0.641 0.392 -1.446 0.392 -2.085 0 C 36.764 10.016 29.933 7.787 23.93 7.787 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path class="svg-black-white" d="M 11.953 39.751 c -0.855 0 -1.646 -0.553 -1.911 -1.413 c -2.26 -7.346 -0.825 -15.376 3.655 -20.458 c 3.241 -3.678 7.71 -5.331 12.273 -4.536 c 1.088 0.19 1.816 1.226 1.626 2.314 c -0.19 1.088 -1.23 1.818 -2.314 1.626 c -3.199 -0.557 -6.251 0.592 -8.585 3.24 c -3.58 4.062 -4.692 10.592 -2.832 16.638 c 0.325 1.056 -0.268 2.175 -1.324 2.5 C 12.346 39.722 12.148 39.751 11.953 39.751 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
10
frontend-old-ember/app/components/svgs/plus-black.hbs
Normal file
10
frontend-old-ember/app/components/svgs/plus-black.hbs
Normal file
|
@ -0,0 +1,10 @@
|
|||
{{!--Source: https://www.iconpacks.net/free-icon/plus-11960.html--}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve" class="{{@class}}">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path class="svg-black-white" d="M 45 90 c -2.761 0 -5 -2.238 -5 -5 V 5 c 0 -2.761 2.239 -5 5 -5 c 2.762 0 5 2.239 5 5 v 80 C 50 87.762 47.762 90 45 90 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path class="svg-black-white" d="M 85 50 H 5 c -2.761 0 -5 -2.238 -5 -5 c 0 -2.761 2.239 -5 5 -5 h 80 c 2.762 0 5 2.239 5 5 C 90 47.762 87.762 50 85 50 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
10
frontend-old-ember/app/components/svgs/plus-pink.hbs
Normal file
10
frontend-old-ember/app/components/svgs/plus-pink.hbs
Normal file
|
@ -0,0 +1,10 @@
|
|||
{{!--Source: https://www.iconpacks.net/free-icon/pink-plus-11966.html--}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve" class="{{@class}}">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path d="M 45 90 c -2.761 0 -5 -2.238 -5 -5 V 5 c 0 -2.761 2.239 -5 5 -5 c 2.762 0 5 2.239 5 5 v 80 C 50 87.762 47.762 90 45 90 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(255,49,250); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path d="M 85 50 H 5 c -2.761 0 -5 -2.238 -5 -5 c 0 -2.761 2.239 -5 5 -5 h 80 c 2.762 0 5 2.239 5 5 C 90 47.762 87.762 50 85 50 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(255,49,250); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
10
frontend-old-ember/app/components/svgs/reload-coloured.hbs
Normal file
10
frontend-old-ember/app/components/svgs/reload-coloured.hbs
Normal file
|
@ -0,0 +1,10 @@
|
|||
{{!--https://www.iconpacks.net/free-icon/arrows-reload-2848.html--}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve" class="{{@class}}">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path d="M 78.39 55.325 c -2.02 -0.89 -4.383 0.024 -5.273 2.047 C 68.207 68.512 57.17 75.709 45 75.709 c -12.697 0 -23.618 -7.746 -28.288 -18.76 l 1.808 -0.168 c 1.547 -0.144 2.871 -1.17 3.396 -2.633 c 0.524 -1.462 0.155 -3.096 -0.948 -4.19 l -7.859 -7.797 c -0.019 -0.019 -0.043 -0.031 -0.062 -0.049 c -0.18 -0.171 -0.373 -0.327 -0.583 -0.463 c -0.074 -0.048 -0.154 -0.083 -0.231 -0.125 c -0.165 -0.092 -0.332 -0.179 -0.51 -0.248 c -0.095 -0.036 -0.192 -0.061 -0.289 -0.09 c -0.166 -0.05 -0.332 -0.094 -0.506 -0.122 c -0.116 -0.019 -0.232 -0.027 -0.35 -0.035 C 10.482 41.022 10.39 41 10.292 41 c -0.068 0 -0.132 0.017 -0.2 0.02 c -0.057 0.003 -0.113 -0.008 -0.169 -0.003 c -0.066 0.006 -0.128 0.03 -0.193 0.04 c -0.166 0.024 -0.327 0.056 -0.485 0.1 c -0.109 0.03 -0.215 0.061 -0.32 0.099 c -0.16 0.059 -0.313 0.129 -0.462 0.207 c -0.095 0.049 -0.19 0.096 -0.281 0.153 c -0.15 0.094 -0.287 0.201 -0.422 0.313 c -0.077 0.063 -0.158 0.12 -0.23 0.19 C 7.37 42.269 7.231 42.437 7.1 42.612 c -0.031 0.041 -0.071 0.073 -0.1 0.115 l -0.025 0.036 c 0 0 -0.001 0.001 -0.001 0.001 l -6.266 9.072 c -0.883 1.278 -0.945 2.952 -0.161 4.294 c 0.722 1.233 2.041 1.979 3.452 1.979 c 0.123 0 0.247 -0.006 0.37 -0.017 l 4.078 -0.378 C 13.721 72.83 28.11 83.709 45 83.709 c 15.339 0 29.249 -9.071 35.437 -23.11 C 81.327 58.577 80.411 56.216 78.39 55.325 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(255,123,123); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path d="M 89.291 38.164 c 0.883 -1.278 0.946 -2.952 0.161 -4.293 c -0.784 -1.341 -2.271 -2.108 -3.821 -1.963 l -4.078 0.378 C 76.28 17.17 61.89 6.292 45 6.292 c -15.339 0 -29.249 9.071 -35.436 23.11 c -0.891 2.021 0.025 4.382 2.047 5.273 c 2.021 0.892 4.382 -0.025 5.273 -2.047 C 21.794 21.489 32.83 14.292 45 14.292 c 12.697 0 23.619 7.746 28.289 18.76 l -1.808 0.168 c -1.547 0.144 -2.871 1.169 -3.396 2.632 c -0.525 1.462 -0.155 3.096 0.947 4.19 l 7.859 7.798 c 0.061 0.061 0.134 0.105 0.199 0.162 c 0.129 0.113 0.256 0.229 0.399 0.325 c 0.083 0.055 0.174 0.093 0.261 0.142 c 0.14 0.079 0.276 0.163 0.425 0.225 c 0.104 0.043 0.214 0.066 0.322 0.1 c 0.14 0.045 0.277 0.098 0.424 0.128 C 79.179 48.972 79.443 49 79.709 49 c 0.122 0 0.246 -0.006 0.369 -0.017 c 0.068 -0.006 0.131 -0.031 0.198 -0.041 c 0.163 -0.023 0.321 -0.055 0.476 -0.098 c 0.111 -0.03 0.22 -0.062 0.327 -0.102 c 0.158 -0.058 0.308 -0.128 0.456 -0.204 c 0.097 -0.05 0.193 -0.097 0.285 -0.155 c 0.149 -0.093 0.286 -0.201 0.421 -0.312 c 0.077 -0.064 0.158 -0.12 0.23 -0.19 c 0.158 -0.152 0.298 -0.32 0.43 -0.496 c 0.03 -0.04 0.069 -0.072 0.098 -0.113 l 0.024 -0.035 c 0.001 -0.001 0.002 -0.002 0.002 -0.003 L 89.291 38.164 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(123,222,255); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
10
frontend-old-ember/app/components/svgs/reload-outline.hbs
Normal file
10
frontend-old-ember/app/components/svgs/reload-outline.hbs
Normal file
|
@ -0,0 +1,10 @@
|
|||
{{!--Source: https://www.iconpacks.net/free-icon/reload-arrows-2846.html--}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve" class="{{@class}}">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path class="svg-black-white" d="M 79.133 57.837 c -1.012 -0.443 -2.19 0.014 -2.637 1.023 C 70.996 71.339 58.633 79.401 45 79.401 c -17.205 0 -31.5 -12.696 -34.01 -29.211 l 4.442 4.407 c 0.784 0.777 2.051 0.773 2.829 -0.012 c 0.778 -0.783 0.773 -2.05 -0.011 -2.828 l -8.242 -8.178 c -0.012 -0.012 -0.027 -0.019 -0.039 -0.031 c -0.088 -0.083 -0.181 -0.158 -0.283 -0.224 c -0.037 -0.024 -0.076 -0.041 -0.114 -0.062 c -0.083 -0.047 -0.168 -0.091 -0.258 -0.125 c -0.043 -0.017 -0.088 -0.028 -0.132 -0.041 c -0.088 -0.027 -0.176 -0.05 -0.269 -0.065 c -0.053 -0.008 -0.106 -0.012 -0.16 -0.016 C 8.7 43.012 8.651 43 8.598 43 c -0.034 0 -0.066 0.008 -0.1 0.01 c -0.028 0.001 -0.056 -0.004 -0.084 -0.002 c -0.034 0.003 -0.065 0.015 -0.099 0.02 c -0.081 0.012 -0.16 0.028 -0.238 0.049 c -0.055 0.015 -0.11 0.031 -0.163 0.051 c -0.079 0.029 -0.154 0.064 -0.228 0.102 c -0.048 0.025 -0.097 0.049 -0.143 0.078 c -0.074 0.046 -0.142 0.1 -0.209 0.155 c -0.039 0.032 -0.08 0.061 -0.116 0.096 c -0.079 0.075 -0.148 0.159 -0.214 0.246 c -0.015 0.021 -0.035 0.036 -0.05 0.058 L 6.94 43.881 c 0 0 0 0.001 -0.001 0.001 l -6.585 9.535 c -0.628 0.909 -0.4 2.154 0.509 2.782 c 0.347 0.24 0.743 0.354 1.135 0.354 c 0.635 0 1.259 -0.302 1.647 -0.863 l 3.389 -4.907 C 9.832 69.224 25.791 83.401 45 83.401 c 15.218 0 29.018 -9 35.156 -22.928 C 80.602 59.463 80.144 58.282 79.133 57.837 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
<path class="svg-black-white" d="M 89.646 36.583 c 0.628 -0.909 0.4 -2.155 -0.509 -2.782 c -0.909 -0.628 -2.156 -0.4 -2.782 0.509 l -3.389 4.907 C 80.168 20.776 64.209 6.598 45 6.598 c -15.218 0 -29.017 9 -35.156 22.928 c -0.445 1.011 0.013 2.191 1.023 2.637 c 1.01 0.446 2.192 -0.012 2.637 -1.023 C 19.004 18.661 31.367 10.598 45 10.598 c 17.204 0 31.499 12.695 34.009 29.21 l -4.441 -4.407 c -0.785 -0.778 -2.05 -0.773 -2.829 0.011 c -0.777 0.784 -0.772 2.05 0.011 2.829 l 8.236 8.171 c 0.001 0.001 0.001 0.001 0.002 0.002 l 0.005 0.005 c 0.022 0.022 0.049 0.038 0.072 0.058 c 0.073 0.066 0.146 0.13 0.227 0.185 c 0.039 0.026 0.083 0.044 0.124 0.067 c 0.072 0.041 0.142 0.084 0.219 0.116 c 0.05 0.021 0.104 0.031 0.155 0.048 c 0.072 0.023 0.142 0.05 0.217 0.065 c 0.129 0.026 0.261 0.04 0.394 0.04 c 0.062 0 0.123 -0.003 0.185 -0.009 c 0.032 -0.003 0.062 -0.015 0.094 -0.019 c 0.084 -0.012 0.166 -0.028 0.246 -0.05 c 0.054 -0.015 0.106 -0.03 0.158 -0.049 c 0.08 -0.029 0.156 -0.064 0.231 -0.103 c 0.048 -0.025 0.096 -0.049 0.143 -0.077 c 0.073 -0.046 0.14 -0.098 0.206 -0.153 c 0.04 -0.033 0.082 -0.062 0.119 -0.099 c 0.078 -0.075 0.147 -0.158 0.212 -0.245 c 0.016 -0.021 0.036 -0.037 0.051 -0.059 l 0.013 -0.018 c 0 0 0 -0.001 0.001 -0.001 L 89.646 36.583 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
6
frontend-old-ember/app/components/timeline.hbs
Normal file
6
frontend-old-ember/app/components/timeline.hbs
Normal file
|
@ -0,0 +1,6 @@
|
|||
<div class="timeline">
|
||||
{{#each @notes as |note|}}
|
||||
<Note @isInTimeline="true" @note={{note}}/>
|
||||
<hr class="timeline-separator">
|
||||
{{/each}}
|
||||
</div>
|
0
frontend-old-ember/app/components/timeline/.gitkeep
Normal file
0
frontend-old-ember/app/components/timeline/.gitkeep
Normal file
1
frontend-old-ember/app/components/timeline/header.hbs
Normal file
1
frontend-old-ember/app/components/timeline/header.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
16
frontend-old-ember/app/components/util/formatter.hbs
Normal file
16
frontend-old-ember/app/components/util/formatter.hbs
Normal file
|
@ -0,0 +1,16 @@
|
|||
<div class="{{@classes}}">
|
||||
{{#if (equals @server "mastodon")}}
|
||||
<Note::Formatter::Mastodon>{{@content}}Masto</Note::Formatter::Mastodon>
|
||||
{{else if (equals @server "misskey")}}
|
||||
<Note::Formatter::Misskey>{{@content}}Misskey</Note::Formatter::Misskey>
|
||||
{{else if (equals @server "akoma")}}
|
||||
<Note::Formatter::Akoma>{{@content}}Akoma</Note::Formatter::Akoma>
|
||||
{{else if (equals @server "linstrom")}}
|
||||
<Note::Formatter::Linstrom>{{@content}}Linstrom</Note::Formatter::Linstrom>
|
||||
{{else if (equals @server "wafrn")}}
|
||||
<Note::Formatter::Wafrn>{{@content}}Wafrn</Note::Formatter::Wafrn>
|
||||
{{else}}
|
||||
<Note::Formatter::Linstrom
|
||||
>{{@content}}Unkown:{{@server}}</Note::Formatter::Linstrom>
|
||||
{{/if}}
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
<p>{{@content}}</p>
|
14
frontend-old-ember/app/components/util/formatter/akoma.ts
Normal file
14
frontend-old-ember/app/components/util/formatter/akoma.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import Component from '@glimmer/component';
|
||||
|
||||
export interface NoteFormatterAkomaSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class NoteFormatterAkoma extends Component<NoteFormatterAkomaSignature> {}
|
|
@ -0,0 +1,2 @@
|
|||
<p>{{@content}}</p>
|
||||
{{yield}}
|
14
frontend-old-ember/app/components/util/formatter/linstrom.ts
Normal file
14
frontend-old-ember/app/components/util/formatter/linstrom.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import Component from '@glimmer/component';
|
||||
|
||||
export interface NoteFormatterLinstromSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class NoteFormatterLinstrom extends Component<NoteFormatterLinstromSignature> {}
|
|
@ -0,0 +1,2 @@
|
|||
<p>{{@content}}</p>
|
||||
{{yield}}
|
14
frontend-old-ember/app/components/util/formatter/mastodon.ts
Normal file
14
frontend-old-ember/app/components/util/formatter/mastodon.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import Component from '@glimmer/component';
|
||||
|
||||
export interface NoteFormatterMastodonSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class NoteFormatterMastodon extends Component<NoteFormatterMastodonSignature> {}
|
|
@ -0,0 +1,2 @@
|
|||
<p>{{@content}}</p>
|
||||
{{yield}}
|
14
frontend-old-ember/app/components/util/formatter/misskey.ts
Normal file
14
frontend-old-ember/app/components/util/formatter/misskey.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import Component from '@glimmer/component';
|
||||
|
||||
export interface NoteFormatterMisskeySignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class NoteFormatterMisskey extends Component<NoteFormatterMisskeySignature> {}
|
|
@ -0,0 +1,2 @@
|
|||
<p>{{@content}}</p>
|
||||
{{yield}}
|
14
frontend-old-ember/app/components/util/formatter/wafrn.ts
Normal file
14
frontend-old-ember/app/components/util/formatter/wafrn.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import Component from '@glimmer/component';
|
||||
|
||||
export interface NoteFormatterWafrnSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class NoteFormatterWafrn extends Component<NoteFormatterWafrnSignature> {}
|
18
frontend-old-ember/app/components/util/mail-entry.hbs
Normal file
18
frontend-old-ember/app/components/util/mail-entry.hbs
Normal file
|
@ -0,0 +1,18 @@
|
|||
<div class="mail-entry {{@wrapper-classes}}">
|
||||
<label>
|
||||
Email
|
||||
{{!--<div class="filling-spacer"/>--}}
|
||||
<Input
|
||||
class="mail-input {{if this.mailOk "mail-input-ok" "mail-input-error"}} {{@input-classes}}"
|
||||
@type="text"
|
||||
@value={{this.args.data.mail}}
|
||||
placeholder="Email address"
|
||||
{{on "change" this.checkMail}}
|
||||
/>
|
||||
</label>
|
||||
{{#if this.mailOk}}
|
||||
<p class="mail-ok mail-status">✔</p>
|
||||
{{else}}
|
||||
<p class="mail-error mail-status">X</p>
|
||||
{{/if}}
|
||||
</div>
|
27
frontend-old-ember/app/components/util/mail-entry.ts
Normal file
27
frontend-old-ember/app/components/util/mail-entry.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { action } from '@ember/object';
|
||||
import { map } from '@ember/object/computed';
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
|
||||
const re = /.+@\S+\.\S+/;
|
||||
|
||||
export interface UtilMailEntrySignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {
|
||||
data: { mail: string; valid: boolean };
|
||||
};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class UtilMailEntry extends Component<UtilMailEntrySignature> {
|
||||
@tracked mailOk = this.args.data.valid;
|
||||
@action checkMail() {
|
||||
this.args.data.valid = re.test(this.args.data.mail);
|
||||
this.mailOk = this.args.data.valid;
|
||||
}
|
||||
}
|
40
frontend-old-ember/app/components/util/map-edit.hbs
Normal file
40
frontend-old-ember/app/components/util/map-edit.hbs
Normal file
|
@ -0,0 +1,40 @@
|
|||
<div class="{{@wrapper-classes}}">
|
||||
{{#if @readonly}}
|
||||
<ul>
|
||||
{{#each this.args.list as |element|}}
|
||||
<li>
|
||||
<div class="string-array-element-wrapper">
|
||||
<p class="{{@element-key-classes}}">{{element.key}}</p>
|
||||
<p class="{{@element-value-classes}}">{{element.value}}</p>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<ul>
|
||||
{{#each this.args.list as |element index|}}
|
||||
<li>
|
||||
<div class="string-array-element-wrapper">
|
||||
<Input @type="text" @value={{element.key}} />
|
||||
<Input @type="text" @value={{element.value}} />
|
||||
<div
|
||||
class="{{@remove-element-classes}}"
|
||||
type="button"
|
||||
{{on "click" (fn this.removeElement index)}}
|
||||
>
|
||||
X
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
</ul>
|
||||
<div
|
||||
class="{{@add-element-classes}}"
|
||||
type="button"
|
||||
{{on "click" this.addElement}}
|
||||
>
|
||||
Add element
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
36
frontend-old-ember/app/components/util/map-edit.ts
Normal file
36
frontend-old-ember/app/components/util/map-edit.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import MutableArray from '@ember/array/mutable';
|
||||
import { action } from '@ember/object';
|
||||
import Component from '@glimmer/component';
|
||||
|
||||
export interface UtilMapEditSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {
|
||||
list: MutableArray<{ key: string; value: string }>;
|
||||
prefix: string;
|
||||
onNewElement: (index: number) => void;
|
||||
onDeleteElement: (index: number) => void;
|
||||
};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class UtilMapEdit extends Component<UtilMapEditSignature> {
|
||||
@action addElement() {
|
||||
MutableArray.apply(this.args.list);
|
||||
this.args.list.pushObject({ key: '', value: '' });
|
||||
if (this.args.onNewElement)
|
||||
this.args.onNewElement(this.args.list.length - 1);
|
||||
}
|
||||
|
||||
@action removeElement(index: number) {
|
||||
MutableArray.apply(this.args.list);
|
||||
//let index = this.args.list.find((elem) => elem == content)
|
||||
//let index = this.listCopy.findIndex((d) => d == content)
|
||||
this.args.list.removeAt(index);
|
||||
if (this.args.onDeleteElement) this.args.onDeleteElement(index);
|
||||
}
|
||||
}
|
26
frontend-old-ember/app/components/util/multiselect.hbs
Normal file
26
frontend-old-ember/app/components/util/multiselect.hbs
Normal file
|
@ -0,0 +1,26 @@
|
|||
<div class={{@wrapper-class}}>
|
||||
{{#if @readonly}}
|
||||
<ul>
|
||||
{{#each this.args.elements as |element|}}
|
||||
{{#if element.checked}}
|
||||
<li>
|
||||
<p>{{element.name}}</p>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
{{#each this.args.elements as |element|}}
|
||||
<label class={{@label-class}}>
|
||||
{{element.description}}
|
||||
<Input
|
||||
@type="checkbox"
|
||||
name="{{element.name}}"
|
||||
class="{{@input-classes}}"
|
||||
@checked={{element.checked}}
|
||||
{{on "change" this.onChange}}
|
||||
/>
|
||||
</label>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
21
frontend-old-ember/app/components/util/multiselect.ts
Normal file
21
frontend-old-ember/app/components/util/multiselect.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { action } from '@ember/object';
|
||||
import Component from '@glimmer/component';
|
||||
|
||||
export interface UtilMultiselectSignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {
|
||||
elements: Array<{ name: string; checked: boolean; description: string }>;
|
||||
};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class UtilMultiselect extends Component<UtilMultiselectSignature> {
|
||||
@action onChange() {
|
||||
console.log(this.args.elements);
|
||||
}
|
||||
}
|
16
frontend-old-ember/app/components/util/one-of-array.hbs
Normal file
16
frontend-old-ember/app/components/util/one-of-array.hbs
Normal file
|
@ -0,0 +1,16 @@
|
|||
<div class="{{@wrapper-class}}">
|
||||
{{#if @readonly}}
|
||||
<p class="{{@element-classes}}">{{@selected}}</p>
|
||||
{{else}}
|
||||
{{#each @elements as |element index|}}
|
||||
<RadioButton
|
||||
@value="{{element}}"
|
||||
@groupValue={{@selected}}
|
||||
@name={{@name}}
|
||||
@required={{@required}}
|
||||
>
|
||||
{{element}}
|
||||
</RadioButton>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
38
frontend-old-ember/app/components/util/string-array.hbs
Normal file
38
frontend-old-ember/app/components/util/string-array.hbs
Normal file
|
@ -0,0 +1,38 @@
|
|||
<div class="{{@wrapper-classes}}">
|
||||
{{#if @readonly}}
|
||||
<ul>
|
||||
{{#each this.args.list as |element|}}
|
||||
<p class="{{@readonly-element-classes}}">{{element.value}}</p>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<ul>
|
||||
{{#each this.args.list as |element index|}}
|
||||
<li>
|
||||
<div class="string-array-element-wrapper {{@element-wrapper-classes}}">
|
||||
<Input
|
||||
class="{{@element-classes}}"
|
||||
@type="text"
|
||||
@value={{element.value}}
|
||||
/>
|
||||
<div
|
||||
class="{{@remove-element-classes}}"
|
||||
type="button"
|
||||
{{on "click" (fn this.removeElement index)}}
|
||||
>
|
||||
X
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
</ul>
|
||||
<div
|
||||
class="{{@add-element-classes}}"
|
||||
type="button"
|
||||
{{on "click" this.addElement}}
|
||||
>
|
||||
Add element
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
56
frontend-old-ember/app/components/util/string-array.ts
Normal file
56
frontend-old-ember/app/components/util/string-array.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
import MutableArray from '@ember/array/mutable';
|
||||
import { action } from '@ember/object';
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
|
||||
export interface UtilStringArraySignature {
|
||||
// The arguments accepted by the component
|
||||
Args: {
|
||||
list: MutableArray<{ value: string }>;
|
||||
prefix: string;
|
||||
onNewElement: (index: number) => void;
|
||||
onDeleteElement: (index: number) => void;
|
||||
};
|
||||
// Any blocks yielded by the component
|
||||
Blocks: {
|
||||
default: [];
|
||||
};
|
||||
// The element to which `...attributes` is applied in the component template
|
||||
Element: null;
|
||||
}
|
||||
|
||||
export default class UtilStringArray extends Component<UtilStringArraySignature> {
|
||||
@action addElement() {
|
||||
MutableArray.apply(this.args.list);
|
||||
this.args.list.pushObject({ value: '' });
|
||||
if (this.args.onNewElement)
|
||||
this.args.onNewElement(this.args.list.length - 1);
|
||||
}
|
||||
|
||||
@action removeElement(index: number) {
|
||||
MutableArray.apply(this.args.list);
|
||||
//let index = this.args.list.find((elem) => elem == content)
|
||||
//let index = this.listCopy.findIndex((d) => d == content)
|
||||
this.args.list.removeAt(index);
|
||||
if (this.args.onDeleteElement) this.args.onDeleteElement(index);
|
||||
}
|
||||
|
||||
transformArrayIntoUsable(arr: Array<string>): { [key: number]: string } {
|
||||
const out: { [key: number]: string } = {};
|
||||
const tmp = arr.map((elem: string, index: number) => {
|
||||
out[index] = elem;
|
||||
return elem;
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
countElemsInObj(obj: any): number {
|
||||
let count = 0;
|
||||
|
||||
for (const prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) ++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
14
frontend-old-ember/app/config/environment.d.ts
vendored
Normal file
14
frontend-old-ember/app/config/environment.d.ts
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Type declarations for
|
||||
* import config from 'frontend-reactive/config/environment'
|
||||
*/
|
||||
declare const config: {
|
||||
environment: string;
|
||||
modulePrefix: string;
|
||||
podModulePrefix: string;
|
||||
locationType: 'history' | 'hash' | 'none';
|
||||
rootURL: string;
|
||||
APP: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export default config;
|
0
frontend-old-ember/app/controllers/.gitkeep
Normal file
0
frontend-old-ember/app/controllers/.gitkeep
Normal file
29
frontend-old-ember/app/formats.js
Normal file
29
frontend-old-ember/app/formats.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
export default {
|
||||
time: {
|
||||
hhmmss: {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
second: 'numeric',
|
||||
},
|
||||
},
|
||||
date: {
|
||||
hhmmss: {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
second: 'numeric',
|
||||
},
|
||||
},
|
||||
number: {
|
||||
compact: {
|
||||
notation: 'compact',
|
||||
},
|
||||
EUR: {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
},
|
||||
USD: {
|
||||
style: 'currency',
|
||||
currency: 'USD',
|
||||
},
|
||||
},
|
||||
};
|
0
frontend-old-ember/app/helpers/.gitkeep
Normal file
0
frontend-old-ember/app/helpers/.gitkeep
Normal file
7
frontend-old-ember/app/helpers/equals.ts
Normal file
7
frontend-old-ember/app/helpers/equals.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { helper } from '@ember/component/helper';
|
||||
|
||||
export default helper(function equals(args) {
|
||||
if (args.length != 2) return false;
|
||||
console.log(args[0], args[1]);
|
||||
return args[0] == args[1];
|
||||
});
|
24
frontend-old-ember/app/helpers/formatter.ts
Normal file
24
frontend-old-ember/app/helpers/formatter.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { helper } from '@ember/component/helper'
|
||||
|
||||
class Token {
|
||||
declare token: string
|
||||
declare elements: Array<string | Token>
|
||||
|
||||
public constructor(token: string) {
|
||||
this.token = token
|
||||
this.elements = new Array()
|
||||
}
|
||||
}
|
||||
|
||||
export default helper(function formatter(
|
||||
positional: Array<string>,
|
||||
named: {
|
||||
matchers: Array<{ match: RegExp; replace: string }>
|
||||
},
|
||||
): string {
|
||||
let out = positional[0] ?? ''
|
||||
named.matchers.forEach((x) => {
|
||||
out = out.replaceAll(x.match, x.replace)
|
||||
})
|
||||
return out
|
||||
})
|
14
frontend-old-ember/app/helpers/is-valid-mail.ts
Normal file
14
frontend-old-ember/app/helpers/is-valid-mail.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { helper } from '@ember/component/helper';
|
||||
|
||||
const re = /.+@\S+\.\S+/;
|
||||
|
||||
// Helper to check if a given email is *probably* valid
|
||||
// Ofc, the only surefire way to check if an email exists is to send a test mail to it.
|
||||
// This sending is expensive however, and thus some mostly sane defaults can be checked for
|
||||
// beforehand. "Bananentürkis" for example is obviously not a valid address
|
||||
export default helper(function isValidMail(positional: string[] /*, named*/) {
|
||||
for (const mail of positional) {
|
||||
if (!re.test(mail)) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
6
frontend-old-ember/app/helpers/isLandscape.ts
Normal file
6
frontend-old-ember/app/helpers/isLandscape.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export default function isLandscape(): boolean {
|
||||
return (
|
||||
Math.min(screen.availHeight, window.innerHeight) <
|
||||
Math.min(screen.availWidth, window.innerWidth)
|
||||
);
|
||||
}
|
24
frontend-old-ember/app/index.html
Normal file
24
frontend-old-ember/app/index.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>FrontendReactive</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
{{content-for "head"}}
|
||||
|
||||
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
|
||||
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/frontend-reactive.css">
|
||||
|
||||
{{content-for "head-footer"}}
|
||||
</head>
|
||||
<body>
|
||||
{{content-for "body"}}
|
||||
|
||||
<script src="{{rootURL}}assets/vendor.js"></script>
|
||||
<script src="{{rootURL}}assets/frontend-reactive.js"></script>
|
||||
|
||||
{{content-for "body-footer"}}
|
||||
</body>
|
||||
</html>
|
0
frontend-old-ember/app/models/.gitkeep
Normal file
0
frontend-old-ember/app/models/.gitkeep
Normal file
36
frontend-old-ember/app/models/account.ts
Normal file
36
frontend-old-ember/app/models/account.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import Model, { attr, hasMany, type AsyncHasMany } from '@ember-data/model';
|
||||
import type CustomAccountFieldModel from './custom-account-field';
|
||||
import type MediaMetadataModel from './media-metadata';
|
||||
import type OriginServer from './origin-server';
|
||||
|
||||
export default class Account extends Model {
|
||||
@attr declare createdAt: Date;
|
||||
@attr declare updatedAt: Date;
|
||||
@attr declare username: string;
|
||||
@attr declare originServer: OriginServer;
|
||||
@attr declare originServerId: number;
|
||||
@attr declare displayName: string;
|
||||
@hasMany('custom-account-field')
|
||||
declare customFields: AsyncHasMany<CustomAccountFieldModel>;
|
||||
@attr declare customFieldIds: Array<number>;
|
||||
@attr declare isBot: boolean;
|
||||
@attr declare description: string;
|
||||
@attr declare icon: MediaMetadataModel;
|
||||
@attr declare iconId: string;
|
||||
@attr declare banner: MediaMetadataModel;
|
||||
@attr declare bannerId: string;
|
||||
@attr declare background: MediaMetadataModel;
|
||||
@attr declare backgroundId: string;
|
||||
@attr declare relationIds: Array<number>;
|
||||
@attr declare indexable: boolean;
|
||||
@attr declare restrictedFollow: boolean;
|
||||
@attr declare identifiesAs: Array<string>;
|
||||
@attr declare pronouns: Array<string>;
|
||||
@attr declare roles: Array<string>;
|
||||
}
|
||||
|
||||
declare module 'ember-data/types/registries/model' {
|
||||
export default interface ModelRegistry {
|
||||
account: Account;
|
||||
}
|
||||
}
|
16
frontend-old-ember/app/models/custom-account-field.ts
Normal file
16
frontend-old-ember/app/models/custom-account-field.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import Model, { attr } from '@ember-data/model';
|
||||
|
||||
export default class CustomAccountField extends Model {
|
||||
@attr declare createdAt: Date;
|
||||
@attr declare updatedAt: Date;
|
||||
@attr declare key: string;
|
||||
@attr declare value: string;
|
||||
@attr declare verified?: boolean;
|
||||
@attr declare belongsToId: string;
|
||||
}
|
||||
|
||||
declare module 'ember-data/types/registries/model' {
|
||||
export default interface ModelRegistry {
|
||||
customAccountField: CustomAccountField;
|
||||
}
|
||||
}
|
17
frontend-old-ember/app/models/emote.ts
Normal file
17
frontend-old-ember/app/models/emote.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import Model, { attr } from '@ember-data/model';
|
||||
import type MediaMetadataModel from './media-metadata';
|
||||
import type OriginServer from './origin-server';
|
||||
|
||||
export default class Emote extends Model {
|
||||
@attr declare metadataId: string;
|
||||
@attr declare metadata: MediaMetadataModel;
|
||||
@attr declare name: string;
|
||||
@attr declare serverId: number;
|
||||
@attr declare server: OriginServer;
|
||||
}
|
||||
|
||||
declare module 'ember-data/types/registries/model' {
|
||||
export default interface ModelRegistry {
|
||||
emote: Emote;
|
||||
}
|
||||
}
|
18
frontend-old-ember/app/models/media-metadata.ts
Normal file
18
frontend-old-ember/app/models/media-metadata.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import Model, { attr } from '@ember-data/model';
|
||||
|
||||
export default class MediaMetadata extends Model {
|
||||
@attr declare createdAt: Date;
|
||||
@attr declare updatedAt: Date;
|
||||
@attr declare isRemote: boolean;
|
||||
@attr declare url: string;
|
||||
@attr declare mimeType: string;
|
||||
@attr declare name: string;
|
||||
@attr declare altText: string;
|
||||
@attr declare blurred: boolean;
|
||||
}
|
||||
|
||||
declare module 'ember-data/types/registries/model' {
|
||||
export default interface ModelRegistry {
|
||||
mediaMetadata: MediaMetadata;
|
||||
}
|
||||
}
|
32
frontend-old-ember/app/models/note.ts
Normal file
32
frontend-old-ember/app/models/note.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import Model, { attr, hasMany, type AsyncHasMany } from '@ember-data/model';
|
||||
import type AccountModel from './account';
|
||||
import type MediaMetadataModel from './media-metadata';
|
||||
import type OriginServer from './origin-server';
|
||||
|
||||
export default class Note extends Model {
|
||||
@attr declare content: string;
|
||||
@attr declare originServer: OriginServer;
|
||||
@attr declare originServerId: number;
|
||||
@attr declare reactionCount: number;
|
||||
@attr declare createdAt: Date;
|
||||
@attr declare updatedAt: Date;
|
||||
@attr declare author: AccountModel;
|
||||
@attr declare authorId: string;
|
||||
@attr declare contentWarning?: string;
|
||||
@attr declare inReplyToId?: string;
|
||||
@attr declare quotesId?: string;
|
||||
@attr declare emoteIds?: Array<string>;
|
||||
@hasMany('media-metadata')
|
||||
declare attachments: AsyncHasMany<MediaMetadataModel>;
|
||||
@attr declare attachmentIds: Array<string>;
|
||||
@attr declare accessLevel: number;
|
||||
@hasMany('account') declare pings?: AsyncHasMany<AccountModel>;
|
||||
@attr declare pingIds?: Array<string>;
|
||||
@attr declare reactionIds: Array<number>;
|
||||
}
|
||||
|
||||
declare module 'ember-data/types/registries/model' {
|
||||
export default interface ModelRegistry {
|
||||
note: Note;
|
||||
}
|
||||
}
|
14
frontend-old-ember/app/models/origin-server.ts
Normal file
14
frontend-old-ember/app/models/origin-server.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import Model, { attr } from '@ember-data/model';
|
||||
|
||||
export default class OriginServer extends Model {
|
||||
@attr() declare serverType: string;
|
||||
@attr() declare name: string;
|
||||
@attr() declare iconUrl: string;
|
||||
@attr() declare isSelf: boolean;
|
||||
}
|
||||
|
||||
declare module 'ember-data/types/registries/model' {
|
||||
export default interface ModelRegistry {
|
||||
originServer: OriginServer;
|
||||
}
|
||||
}
|
15
frontend-old-ember/app/models/reaction.ts
Normal file
15
frontend-old-ember/app/models/reaction.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import Model, { attr } from '@ember-data/model';
|
||||
import type EmoteModel from './emote';
|
||||
|
||||
export default class Reaction extends Model {
|
||||
@attr declare noteId: string;
|
||||
@attr declare reactorId: string;
|
||||
@attr declare emoteId: number;
|
||||
@attr declare emote: EmoteModel;
|
||||
}
|
||||
|
||||
declare module 'ember-data/types/registries/model' {
|
||||
export default interface ModelRegistry {
|
||||
reaction: Reaction;
|
||||
}
|
||||
}
|
16
frontend-old-ember/app/models/relation.ts
Normal file
16
frontend-old-ember/app/models/relation.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import Model, { attr } from '@ember-data/model';
|
||||
|
||||
export default class Relation extends Model {
|
||||
@attr declare createdAt: Date;
|
||||
@attr declare updatedAt: Date;
|
||||
@attr declare fromId: string;
|
||||
@attr declare toId: string;
|
||||
@attr declare requested: boolean;
|
||||
@attr declare accepted: boolean;
|
||||
}
|
||||
|
||||
declare module 'ember-data/types/registries/model' {
|
||||
export default interface ModelRegistry {
|
||||
relation: Relation;
|
||||
}
|
||||
}
|
64
frontend-old-ember/app/models/role.ts
Normal file
64
frontend-old-ember/app/models/role.ts
Normal file
|
@ -0,0 +1,64 @@
|
|||
// Code generated by cmd/RolesApiTypeGenerator DO NOT EDIT.
|
||||
// If you need to refresh the content, run go generate again
|
||||
import Model, { attr } from '@ember-data/model';
|
||||
|
||||
export default class Role extends Model {
|
||||
@attr() declare createdAt: Date;
|
||||
@attr() declare updatedAt: Date;
|
||||
@attr() declare name: string;
|
||||
@attr() declare priority: number;
|
||||
@attr() declare isUserRole: boolean;
|
||||
@attr() declare isBuiltIn: boolean;
|
||||
|
||||
@attr() declare canSendCustomReactions?: boolean;
|
||||
@attr() declare autoCwPostsText?: string;
|
||||
@attr() declare withholdNotesRegexes?: Array<string>;
|
||||
@attr() declare canAssignRoles?: boolean;
|
||||
@attr() declare canSupressInteractionsBetweenUsers?: boolean;
|
||||
@attr() declare canSendCustomEmotes?: boolean;
|
||||
@attr() declare canOverwriteDisplayNames?: boolean;
|
||||
@attr() declare canManageCustomEmotes?: boolean;
|
||||
@attr() declare canDeleteNotes?: boolean;
|
||||
@attr() declare canManageAvatarDecorations?: boolean;
|
||||
@attr() declare canManageAds?: boolean;
|
||||
@attr() declare blockedUsers?: Array<string>;
|
||||
@attr() declare hasMentionCountLimit?: boolean;
|
||||
@attr() declare disallowInteractionsWith?: Array<string>;
|
||||
@attr() declare withholdNotesBasedOnRegex?: boolean;
|
||||
@attr() declare fullAdmin?: boolean;
|
||||
@attr() declare canSendAnnouncements?: boolean;
|
||||
@attr() declare autoNsfwMedia?: boolean;
|
||||
@attr() declare scanCreatedPublicNotes?: boolean;
|
||||
@attr() declare scanCreatedPrivateNotes?: boolean;
|
||||
@attr() declare canSendFollowerOnlyNotes?: boolean;
|
||||
@attr() declare canSendPrivateNotes?: boolean;
|
||||
@attr() declare canIncludeSurvey?: boolean;
|
||||
@attr() declare canChangeDisplayName?: boolean;
|
||||
@attr() declare canLogin?: boolean;
|
||||
@attr() declare canAffectOtherAdmins?: boolean;
|
||||
@attr() declare autoCwPosts?: boolean;
|
||||
@attr() declare scanCreatedFollowerOnlyNotes?: boolean;
|
||||
@attr() declare canViewDeletedNotes?: boolean;
|
||||
@attr() declare mentionLimit?: number;
|
||||
@attr() declare withholdNotesForManualApproval?: boolean;
|
||||
@attr() declare canConfirmWithheldNotes?: boolean;
|
||||
@attr() declare canSendMedia?: boolean;
|
||||
@attr() declare canSendPublicNotes?: boolean;
|
||||
@attr() declare canSendReplies?: boolean;
|
||||
@attr() declare canQuote?: boolean;
|
||||
@attr() declare canIncludeLinks?: boolean;
|
||||
@attr() declare canRecoverDeletedNotes?: boolean;
|
||||
@attr() declare canMentionOthers?: boolean;
|
||||
@attr() declare scanCreatedLocalNotes?: boolean;
|
||||
@attr() declare canSendLocalNotes?: boolean;
|
||||
@attr() declare canBoost?: boolean;
|
||||
@attr() declare canFederateFedi?: boolean;
|
||||
@attr() declare canFederateBsky?: boolean;
|
||||
@attr() declare canSubmitReports?: boolean;
|
||||
}
|
||||
|
||||
declare module 'ember-data/types/registries/model' {
|
||||
export default interface ModelRegistry {
|
||||
role: Role;
|
||||
}
|
||||
}
|
14
frontend-old-ember/app/router.ts
Normal file
14
frontend-old-ember/app/router.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import EmberRouter from '@ember/routing/router';
|
||||
import config from 'frontend-reactive/config/environment';
|
||||
|
||||
export default class Router extends EmberRouter {
|
||||
location = config.locationType;
|
||||
rootURL = config.rootURL;
|
||||
}
|
||||
|
||||
Router.map(function () {
|
||||
this.route('about');
|
||||
this.route('registerform');
|
||||
this.route('auth');
|
||||
this.route('testing');
|
||||
});
|
0
frontend-old-ember/app/routes/.gitkeep
Normal file
0
frontend-old-ember/app/routes/.gitkeep
Normal file
3
frontend-old-ember/app/routes/about.ts
Normal file
3
frontend-old-ember/app/routes/about.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class AboutRoute extends Route {}
|
4
frontend-old-ember/app/routes/application.ts
Normal file
4
frontend-old-ember/app/routes/application.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import Route from '@ember/routing/route'
|
||||
import { type Registry as Services, service } from '@ember/service'
|
||||
|
||||
export default class ApplicationRoute extends Route {}
|
4
frontend-old-ember/app/routes/auth.ts
Normal file
4
frontend-old-ember/app/routes/auth.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
|
||||
export default class AuthRoute extends Route {}
|
54
frontend-old-ember/app/routes/index.ts
Normal file
54
frontend-old-ember/app/routes/index.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import Route from '@ember/routing/route'
|
||||
import { type Registry as Services, service } from '@ember/service'
|
||||
|
||||
export default class IndexRoute extends Route {
|
||||
@service declare intl: Services['intl']
|
||||
|
||||
beforeModel() {
|
||||
this.intl.setLocale(['en-us'])
|
||||
}
|
||||
|
||||
model() {
|
||||
console.log('root route loaded')
|
||||
return {
|
||||
notes: [
|
||||
{
|
||||
displayname: 'alice',
|
||||
username: 'bob',
|
||||
server: 'example.com',
|
||||
content: 'lorem ipsum',
|
||||
createdAt: Date.now() - 360000,
|
||||
editedAt: Date.now() - 60000,
|
||||
servertype: 'mastodon',
|
||||
},
|
||||
{
|
||||
displayname: 'Melody',
|
||||
username: 'mstar',
|
||||
server: 'woem.men',
|
||||
content:
|
||||
'Grapple keel reef fathom haul wind bilge rat swing the lead belay line pink. Man-of-war mizzenmast killick lookout yo-ho-ho Sail ho gabion careen sutler stern. Draught wherry lookout schooner prow hail-shot spanker Letter of Marque lateen sail strike colors.\n\nLad heave to topgallant scallywag scuppers Spanish Main poop deck spike hulk broadside. Snow take a caulk hornswaggle gaff swab quarter lugger spanker bilge provost. Man-of-war measured fer yer chains lugger cable loaded to the gunwalls prow piracy snow doubloon furl.\n\nDead men tell no tales jib chase guns gunwalls Gold Road smartly nipperkin topsail bilge water Pirate Round. Gaff gunwalls bilged on her anchor bilge water scourge of the seven seas parley ho sheet chase guns squiffy. Scuppers fathom ho quarter gally heave to yardarm coxswain red ensign pink.',
|
||||
createdAt: Date.now() - 3600,
|
||||
servertype: 'linstrom',
|
||||
},
|
||||
{
|
||||
displayname: 'alice',
|
||||
username: 'bob',
|
||||
server: 'example.com',
|
||||
content: 'lorem ipsum',
|
||||
createdAt: Date.now() - 360000,
|
||||
editedAt: Date.now() - 60000,
|
||||
servertype: 'wafrn',
|
||||
},
|
||||
{
|
||||
displayname: 'Melody',
|
||||
username: 'mstar',
|
||||
server: 'woem.men',
|
||||
content:
|
||||
'Grapple keel reef fathom haul wind bilge rat swing the lead belay line pink. Man-of-war mizzenmast killick lookout yo-ho-ho Sail ho gabion careen sutler stern. Draught wherry lookout schooner prow hail-shot spanker Letter of Marque lateen sail strike colors.\n\nLad heave to topgallant scallywag scuppers Spanish Main poop deck spike hulk broadside. Snow take a caulk hornswaggle gaff swab quarter lugger spanker bilge provost. Man-of-war measured fer yer chains lugger cable loaded to the gunwalls prow piracy snow doubloon furl.\n\nDead men tell no tales jib chase guns gunwalls Gold Road smartly nipperkin topsail bilge water Pirate Round. Gaff gunwalls bilged on her anchor bilge water scourge of the seven seas parley ho sheet chase guns squiffy. Scuppers fathom ho quarter gally heave to yardarm coxswain red ensign pink.',
|
||||
createdAt: Date.now() - 3600,
|
||||
servertype: 'unknown',
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
9
frontend-old-ember/app/routes/registerform.ts
Normal file
9
frontend-old-ember/app/routes/registerform.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class RegisterFormRoute extends Route {
|
||||
async model() {
|
||||
return {
|
||||
list: [{ value: 'one' }, { value: 'two' }],
|
||||
};
|
||||
}
|
||||
}
|
3
frontend-old-ember/app/routes/testing.ts
Normal file
3
frontend-old-ember/app/routes/testing.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class TestingRoute extends Route {}
|
143
frontend-old-ember/app/services/auth.ts
Normal file
143
frontend-old-ember/app/services/auth.ts
Normal file
|
@ -0,0 +1,143 @@
|
|||
import Service from '@ember/service';
|
||||
import {
|
||||
startAuthentication,
|
||||
startRegistration,
|
||||
} from '@simplewebauthn/browser';
|
||||
|
||||
export default class AuthService extends Service {
|
||||
async startLogin(username: string) {
|
||||
// Get login options from your server. Here, we also receive the challenge.
|
||||
const response = await fetch('/webauthn/passkey/loginBegin', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: username }),
|
||||
});
|
||||
// Check if the login options are ok.
|
||||
if (!response.ok) {
|
||||
const msg = await response.json();
|
||||
throw new Error('Failed to get login options from server: ' + msg);
|
||||
}
|
||||
// Convert the login options to JSON.
|
||||
const options = await response.json();
|
||||
|
||||
// This triggers the browser to display the passkey / WebAuthn modal (e.g. Face ID, Touch ID, Windows Hello).
|
||||
// A new assertionResponse is created. This also means that the challenge has been signed.
|
||||
const assertionResponse = await startAuthentication(options.publicKey);
|
||||
|
||||
// Send assertionResponse back to server for verification.
|
||||
const verificationResponse = await fetch('/webauthn/passkey/loginFinish', {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(assertionResponse),
|
||||
});
|
||||
|
||||
const msg = await verificationResponse.json();
|
||||
if (verificationResponse.ok) {
|
||||
return;
|
||||
} else {
|
||||
throw new Error(
|
||||
'Bad response code: ' +
|
||||
verificationResponse.status +
|
||||
'. Content: ' +
|
||||
msg,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async startRegistration(username: string) {
|
||||
// Get registration options from your server. Here, we also receive the challenge.
|
||||
const response = await fetch('/webauthn/passkey/registerBegin', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: username }),
|
||||
});
|
||||
|
||||
// Check if the registration options are ok.
|
||||
if (!response.ok) {
|
||||
const msg = await response.json();
|
||||
throw new Error(
|
||||
'User already exists or failed to get registration options from server: ' +
|
||||
msg,
|
||||
);
|
||||
}
|
||||
|
||||
// Convert the registration options to JSON.
|
||||
const options = await response.json();
|
||||
console.log('registration start', options);
|
||||
|
||||
// This triggers the browser to display the passkey / WebAuthn modal (e.g. Face ID, Touch ID, Windows Hello).
|
||||
// A new attestation is created. This also means a new public-private-key pair is created.
|
||||
const attestationResponse = await startRegistration(options.publicKey);
|
||||
|
||||
console.log('Attempting to complete registration', attestationResponse);
|
||||
// Send attestationResponse back to server for verification and storage.
|
||||
const verificationResponse = await fetch(
|
||||
'/webauthn/passkey/registerFinish',
|
||||
{
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(attestationResponse),
|
||||
},
|
||||
);
|
||||
|
||||
const msg = await verificationResponse.json();
|
||||
if (verificationResponse.ok) {
|
||||
return;
|
||||
} else {
|
||||
throw new Error(
|
||||
'Bad response code: ' +
|
||||
verificationResponse.status +
|
||||
'. Content: ' +
|
||||
msg,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the client is currently logged in
|
||||
// Happens via caling an endpoint that's only available if logged in but doesn't return anything other than "ok"
|
||||
async getLoginState(): Promise<boolean> {
|
||||
try {
|
||||
const response = await fetch('/api/test-auth');
|
||||
return response.status >= 200 && response.status < 300;
|
||||
} catch (error: any) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a given username exist on the server
|
||||
// Note: The server enforces this check itself during both registration and login
|
||||
// but provides the information too so that frontends can provide a better UX
|
||||
async doesUsernameExist(username: string): Promise<boolean> {
|
||||
// TODO: Make API call to check if username/handle is already in use
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if a given username is allowed to log in.
|
||||
// This includes a check for the existence of the username in the first place
|
||||
// A username may not log in for various reasons, two of which are the account not being approved yet
|
||||
// or the account being barred login from an admin
|
||||
// Note: The server enforces this check itself during login. However, it also provides an API endpoint
|
||||
// for performing this check to allow frontends to have a better UX
|
||||
async canUsernameLogin(username: string): Promise<boolean> {
|
||||
// Can't login into a non-existing account
|
||||
if (!(await this.doesUsernameExist(username))) return false;
|
||||
// TODO: Make API call to check if username is allowed to login
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't remove this declaration: this is what enables TypeScript to resolve
|
||||
// this service using `Owner.lookup('service:auth')`, as well
|
||||
// as to check when you pass the service name as an argument to the decorator,
|
||||
// like `@service('auth') declare altName: AuthService;`.
|
||||
declare module '@ember/service' {
|
||||
interface Registry {
|
||||
auth: AuthService;
|
||||
}
|
||||
}
|
16
frontend-old-ember/app/styles/app.css
Normal file
16
frontend-old-ember/app/styles/app.css
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* Ember supports plain CSS out of the box. More info: https://cli.emberjs.com/release/advanced-use/stylesheets/ */
|
||||
|
||||
/* Note: CSS is fucking stupid. It applies styles not in the order classes are set on an element,
|
||||
* but in the order they appear in the css files */
|
||||
|
||||
/* @import url("debug.css"); */
|
||||
@import url("fonts.css");
|
||||
@import url("colors.css");
|
||||
@import url("util.css");
|
||||
@import url("util/stringArray.css");
|
||||
@import url("util/mailEntry.css");
|
||||
@import url("svgs.css");
|
||||
@import url("notes.css");
|
||||
@import url("timeline.css");
|
||||
@import url("auth.css");
|
||||
@import url("auth/registerForm.css");
|
0
frontend-old-ember/app/styles/auth.css
Normal file
0
frontend-old-ember/app/styles/auth.css
Normal file
77
frontend-old-ember/app/styles/auth/registerForm.css
Normal file
77
frontend-old-ember/app/styles/auth/registerForm.css
Normal file
|
@ -0,0 +1,77 @@
|
|||
.registration-form {
|
||||
background: var(--secondary);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.registration-form-name-mail-wrapper {
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.registration-form-username {
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.registration-form-displayname-wrapper {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.registration-form-mail-wrapper {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.registration-form-mail-input {
|
||||
width: max-content;
|
||||
|
||||
/* display: flex; */
|
||||
|
||||
/* flex-grow: 1; */
|
||||
}
|
||||
|
||||
.registration-form-description-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.registration-form-gender-wrapper {
|
||||
}
|
||||
|
||||
.registration-form-gender-info {
|
||||
}
|
||||
|
||||
.register-form-being-wrapper {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.registration-form-being-info {
|
||||
}
|
||||
|
||||
.register-form-default-post-mode-wrapper {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.registration-form-default-post-mode-info {
|
||||
}
|
||||
|
||||
.register-form-follow-approval-wrapper {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.register-form-indexable-wrapper {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.register-form-custom-fields-wrapper {
|
||||
flex-grow: 1;
|
||||
width: 80%;
|
||||
margin-bottom: 1em;
|
||||
}
|
152
frontend-old-ember/app/styles/colors-precise.css
Normal file
152
frontend-old-ember/app/styles/colors-precise.css
Normal file
|
@ -0,0 +1,152 @@
|
|||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--text: hsl(273deg 35% 6%);
|
||||
--background: hsl(267deg 36% 95%);
|
||||
--primary: hsl(273deg 37% 27%);
|
||||
--secondary: hsl(307deg 37% 68%);
|
||||
--accent: hsl(318deg 37% 42%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--text: hsl(273deg 35% 94%);
|
||||
--background: hsl(267deg 36% 5%);
|
||||
--primary: hsl(273deg 37% 73%);
|
||||
--secondary: hsl(307deg 37% 32%);
|
||||
--accent: hsl(318deg 37% 58%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--text-5: hsl(273deg 36% 95%);
|
||||
--text-10: hsl(272deg 33% 90%);
|
||||
--text-15: hsl(272deg 33% 85%);
|
||||
--text-20: hsl(273deg 35% 80%);
|
||||
--text-25: hsl(273deg 35% 75%);
|
||||
--text-30: hsl(273deg 35% 70%);
|
||||
--text-35: hsl(273deg 35% 65%);
|
||||
--text-40: hsl(273deg 35% 60%);
|
||||
--text-45: hsl(273deg 35% 55%);
|
||||
--text-50: hsl(273deg 35% 50%);
|
||||
--text-55: hsl(273deg 35% 45%);
|
||||
--text-60: hsl(273deg 35% 40%);
|
||||
--text-65: hsl(273deg 35% 35%);
|
||||
--text-70: hsl(273deg 35% 30%);
|
||||
--text-75: hsl(273deg 35% 25%);
|
||||
--text-80: hsl(273deg 35% 20%);
|
||||
--text-85: hsl(273deg 35% 20%);
|
||||
--text-90: hsl(272deg 33% 10%);
|
||||
--text-95: hsl(273deg 36% 5%);
|
||||
--background-5: hsl(267deg 36% 95%);
|
||||
--background-10: hsl(268deg 37% 90%);
|
||||
--background-15: hsl(267deg 36% 85%);
|
||||
--background-20: hsl(267deg 35% 80%);
|
||||
--background-25: hsl(267deg 35% 75%);
|
||||
--background-30: hsl(267deg 36% 70%);
|
||||
--background-35: hst(267, 36%, 65%);
|
||||
--background-40: hsl(267deg 36% 60%);
|
||||
--background-45: hsl(267deg 36% 55%);
|
||||
--background-50: hsl(267deg 36% 50%);
|
||||
--background-60: hsl(267deg 36% 40%);
|
||||
--background-70: hsl(267deg 36% 30%);
|
||||
--background-80: hsl(267deg 35% 20%);
|
||||
--background-85: hsl(267deg 36% 15%);
|
||||
--background-90: hsl(268deg 37% 10%);
|
||||
--background-95: hsl(267deg 36% 5%);
|
||||
--primary-5: hsl(273deg 36% 95%);
|
||||
--primary-10: hsl(272deg 37% 90%);
|
||||
--primary-20: hsl(273deg 37% 80%);
|
||||
--primary-30: hsl(273deg 37% 70%);
|
||||
--primary-40: hsl(273deg 37% 60%);
|
||||
--primary-50: hsl(273deg 37% 50%);
|
||||
--primary-60: hsl(273deg 37% 40%);
|
||||
--primary-70: hsl(273deg 37% 30%);
|
||||
--primary-80: hsl(273deg 37% 20%);
|
||||
--primary-90: hsl(272deg 37% 10%);
|
||||
--primary-95: hsl(273deg 36% 5%);
|
||||
--secondary-5: hsl(307deg 36% 95%);
|
||||
--secondary-10: hsl(306deg 37% 90%);
|
||||
--secondary-20: hsl(308deg 37% 80%);
|
||||
--secondary-30: hsl(307deg 37% 70%);
|
||||
--secondary-40: hsl(307deg 37% 60%);
|
||||
--secondary-50: hsl(307deg 37% 50%);
|
||||
--secondary-60: hsl(307deg 37% 40%);
|
||||
--secondary-70: hsl(307deg 37% 30%);
|
||||
--secondary-80: hsl(308deg 37% 20%);
|
||||
--secondary-90: hsl(306deg 37% 10%);
|
||||
--secondary-95: hsl(307deg 36% 5%);
|
||||
--accent-5: hsl(320deg 36% 95%);
|
||||
--accent-10: hsl(319deg 37% 90%);
|
||||
--accent-20: hsl(317deg 37% 80%);
|
||||
--accent-30: hsl(318deg 37% 70%);
|
||||
--accent-40: hsl(318deg 37% 60%);
|
||||
--accent-50: hsl(318deg 37% 50%);
|
||||
--accent-60: hsl(318deg 37% 40%);
|
||||
--accent-70: hsl(318deg 37% 30%);
|
||||
--accent-80: hsl(317deg 37% 20%);
|
||||
--accent-90: hsl(319deg 37% 10%);
|
||||
--accent-95: hsl(313deg 36% 5%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--text-50: hsl(273deg 36% 5%);
|
||||
--text-100: hsl(272deg 33% 10%);
|
||||
--text-200: hsl(273deg 35% 20%);
|
||||
--text-300: hsl(273deg 35% 30%);
|
||||
--text-400: hsl(273deg 35% 40%);
|
||||
--text-500: hsl(273deg 35% 50%);
|
||||
--text-600: hsl(273deg 35% 60%);
|
||||
--text-700: hsl(273deg 35% 70%);
|
||||
--text-800: hsl(273deg 35% 80%);
|
||||
--text-900: hsl(272deg 33% 90%);
|
||||
--text-950: hsl(273deg 36% 95%);
|
||||
--background-50: hsl(267deg 36% 5%);
|
||||
--background-100: hsl(268deg 37% 10%);
|
||||
--background-200: hsl(267deg 35% 20%);
|
||||
--background-300: hsl(267deg 36% 30%);
|
||||
--background-400: hsl(267deg 36% 40%);
|
||||
--background-500: hsl(267deg 36% 50%);
|
||||
--background-600: hsl(267deg 36% 60%);
|
||||
--background-700: hsl(267deg 36% 70%);
|
||||
--background-800: hsl(267deg 35% 80%);
|
||||
--background-900: hsl(268deg 37% 90%);
|
||||
--background-950: hsl(267deg 36% 95%);
|
||||
--primary-50: hsl(273deg 36% 5%);
|
||||
--primary-100: hsl(272deg 37% 10%);
|
||||
--primary-200: hsl(273deg 37% 20%);
|
||||
--primary-300: hsl(273deg 37% 30%);
|
||||
--primary-400: hsl(273deg 37% 40%);
|
||||
--primary-500: hsl(273deg 37% 50%);
|
||||
--primary-600: hsl(273deg 37% 60%);
|
||||
--primary-700: hsl(273deg 37% 70%);
|
||||
--primary-800: hsl(273deg 37% 80%);
|
||||
--primary-900: hsl(272deg 37% 90%);
|
||||
--primary-950: hsl(273deg 36% 95%);
|
||||
--secondary-50: hsl(307deg 36% 5%);
|
||||
--secondary-100: hsl(306deg 37% 10%);
|
||||
--secondary-200: hsl(308deg 37% 20%);
|
||||
--secondary-300: hsl(307deg 37% 30%);
|
||||
--secondary-400: hsl(307deg 37% 40%);
|
||||
--secondary-500: hsl(307deg 37% 50%);
|
||||
--secondary-600: hsl(307deg 37% 60%);
|
||||
--secondary-700: hsl(307deg 37% 70%);
|
||||
--secondary-800: hsl(308deg 37% 80%);
|
||||
--secondary-900: hsl(306deg 37% 90%);
|
||||
--secondary-950: hsl(307deg 36% 95%);
|
||||
--accent-50: hsl(313deg 36% 5%);
|
||||
--accent-100: hsl(319deg 37% 10%);
|
||||
--accent-200: hsl(317deg 37% 20%);
|
||||
--accent-300: hsl(318deg 37% 30%);
|
||||
--accent-400: hsl(318deg 37% 40%);
|
||||
--accent-500: hsl(318deg 37% 50%);
|
||||
--accent-600: hsl(318deg 37% 60%);
|
||||
--accent-700: hsl(318deg 37% 70%);
|
||||
--accent-800: hsl(317deg 37% 80%);
|
||||
--accent-900: hsl(319deg 37% 90%);
|
||||
--accent-950: hsl(320deg 36% 95%);
|
||||
}
|
||||
}
|
152
frontend-old-ember/app/styles/colors.css
Normal file
152
frontend-old-ember/app/styles/colors.css
Normal file
|
@ -0,0 +1,152 @@
|
|||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--text: hsl(273deg 35% 6%);
|
||||
--background: hsl(267deg 36% 95%);
|
||||
--primary: hsl(273deg 37% 27%);
|
||||
--secondary: hsl(307deg 37% 68%);
|
||||
--accent: hsl(318deg 37% 42%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--text: hsl(273deg 35% 94%);
|
||||
--background: hsl(267deg 36% 5%);
|
||||
--primary: hsl(273deg 37% 73%);
|
||||
--secondary: hsl(307deg 37% 32%);
|
||||
--accent: hsl(318deg 37% 58%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--text-50: hsl(273deg 36% 95%);
|
||||
--text-100: hsl(272deg 33% 90%);
|
||||
--text-200: hsl(273deg 35% 80%);
|
||||
--text-300: hsl(273deg 35% 70%);
|
||||
--text-400: hsl(273deg 35% 60%);
|
||||
--text-500: hsl(273deg 35% 50%);
|
||||
--text-600: hsl(273deg 35% 40%);
|
||||
--text-700: hsl(273deg 35% 30%);
|
||||
--text-800: hsl(273deg 35% 20%);
|
||||
--text-900: hsl(272deg 33% 10%);
|
||||
--text-950: hsl(273deg 36% 5%);
|
||||
|
||||
--background-50: hsl(267deg 36% 95%);
|
||||
--background-100: hsl(268deg 37% 90%);
|
||||
--background-200: hsl(267deg 35% 80%);
|
||||
--background-300: hsl(267deg 36% 70%);
|
||||
--background-400: hsl(267deg 36% 60%);
|
||||
--background-500: hsl(267deg 36% 50%);
|
||||
--background-600: hsl(267deg 36% 40%);
|
||||
--background-700: hsl(267deg 36% 30%);
|
||||
--background-800: hsl(267deg 35% 20%);
|
||||
--background-900: hsl(268deg 37% 10%);
|
||||
--background-950: hsl(267deg 36% 5%);
|
||||
|
||||
--primary-50: hsl(273deg 36% 95%);
|
||||
--primary-100: hsl(272deg 37% 90%);
|
||||
--primary-200: hsl(273deg 37% 80%);
|
||||
--primary-300: hsl(273deg 37% 70%);
|
||||
--primary-400: hsl(273deg 37% 60%);
|
||||
--primary-500: hsl(273deg 37% 50%);
|
||||
--primary-600: hsl(273deg 37% 40%);
|
||||
--primary-700: hsl(273deg 37% 30%);
|
||||
--primary-800: hsl(273deg 37% 20%);
|
||||
--primary-900: hsl(272deg 37% 10%);
|
||||
--primary-950: hsl(273deg 36% 5%);
|
||||
|
||||
--secondary-50: hsl(307deg 36% 95%);
|
||||
--secondary-100: hsl(306deg 37% 90%);
|
||||
--secondary-200: hsl(308deg 37% 80%);
|
||||
--secondary-300: hsl(307deg 37% 70%);
|
||||
--secondary-400: hsl(307deg 37% 60%);
|
||||
--secondary-500: hsl(307deg 37% 50%);
|
||||
--secondary-600: hsl(307deg 37% 40%);
|
||||
--secondary-700: hsl(307deg 37% 30%);
|
||||
--secondary-800: hsl(308deg 37% 20%);
|
||||
--secondary-900: hsl(306deg 37% 10%);
|
||||
--secondary-950: hsl(307deg 36% 5%);
|
||||
|
||||
--accent-50: hsl(320deg 36% 95%);
|
||||
--accent-100: hsl(319deg 37% 90%);
|
||||
--accent-200: hsl(317deg 37% 80%);
|
||||
--accent-300: hsl(318deg 37% 70%);
|
||||
--accent-400: hsl(318deg 37% 60%);
|
||||
--accent-500: hsl(318deg 37% 50%);
|
||||
--accent-600: hsl(318deg 37% 40%);
|
||||
--accent-700: hsl(318deg 37% 30%);
|
||||
--accent-800: hsl(317deg 37% 20%);
|
||||
--accent-900: hsl(319deg 37% 10%);
|
||||
--accent-950: hsl(313deg 36% 5%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--text-50: hsl(273deg 36% 5%);
|
||||
--text-100: hsl(272deg 33% 10%);
|
||||
--text-200: hsl(273deg 35% 20%);
|
||||
--text-300: hsl(273deg 35% 30%);
|
||||
--text-400: hsl(273deg 35% 40%);
|
||||
--text-500: hsl(273deg 35% 50%);
|
||||
--text-600: hsl(273deg 35% 60%);
|
||||
--text-700: hsl(273deg 35% 70%);
|
||||
--text-800: hsl(273deg 35% 80%);
|
||||
--text-900: hsl(272deg 33% 90%);
|
||||
--text-950: hsl(273deg 36% 95%);
|
||||
|
||||
--background-50: hsl(267deg 36% 5%);
|
||||
--background-100: hsl(268deg 37% 10%);
|
||||
--background-200: hsl(267deg 35% 20%);
|
||||
--background-300: hsl(267deg 36% 30%);
|
||||
--background-400: hsl(267deg 36% 40%);
|
||||
--background-500: hsl(267deg 36% 50%);
|
||||
--background-600: hsl(267deg 36% 60%);
|
||||
--background-700: hsl(267deg 36% 70%);
|
||||
--background-800: hsl(267deg 35% 80%);
|
||||
--background-900: hsl(268deg 37% 90%);
|
||||
--background-950: hsl(267deg 36% 95%);
|
||||
|
||||
--primary-50: hsl(273deg 36% 5%);
|
||||
--primary-100: hsl(272deg 37% 10%);
|
||||
--primary-200: hsl(273deg 37% 20%);
|
||||
--primary-300: hsl(273deg 37% 30%);
|
||||
--primary-400: hsl(273deg 37% 40%);
|
||||
--primary-500: hsl(273deg 37% 50%);
|
||||
--primary-600: hsl(273deg 37% 60%);
|
||||
--primary-700: hsl(273deg 37% 70%);
|
||||
--primary-800: hsl(273deg 37% 80%);
|
||||
--primary-900: hsl(272deg 37% 90%);
|
||||
--primary-950: hsl(273deg 36% 95%);
|
||||
|
||||
--secondary-50: hsl(307deg 36% 5%);
|
||||
--secondary-100: hsl(306deg 37% 10%);
|
||||
--secondary-200: hsl(308deg 37% 20%);
|
||||
--secondary-300: hsl(307deg 37% 30%);
|
||||
--secondary-400: hsl(307deg 37% 40%);
|
||||
--secondary-500: hsl(307deg 37% 50%);
|
||||
--secondary-600: hsl(307deg 37% 60%);
|
||||
--secondary-700: hsl(307deg 37% 70%);
|
||||
--secondary-800: hsl(308deg 37% 80%);
|
||||
--secondary-900: hsl(306deg 37% 90%);
|
||||
--secondary-950: hsl(307deg 36% 95%);
|
||||
|
||||
--accent-50: hsl(313deg 36% 5%);
|
||||
--accent-100: hsl(319deg 37% 10%);
|
||||
--accent-200: hsl(317deg 37% 20%);
|
||||
--accent-300: hsl(318deg 37% 30%);
|
||||
--accent-400: hsl(318deg 37% 40%);
|
||||
--accent-500: hsl(318deg 37% 50%);
|
||||
--accent-600: hsl(318deg 37% 60%);
|
||||
--accent-700: hsl(318deg 37% 70%);
|
||||
--accent-800: hsl(317deg 37% 80%);
|
||||
--accent-900: hsl(319deg 37% 90%);
|
||||
--accent-950: hsl(320deg 36% 95%);
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
background-color: var(--background);
|
||||
color: var(--text);
|
||||
}
|
3
frontend-old-ember/app/styles/debug.css
Normal file
3
frontend-old-ember/app/styles/debug.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
* {
|
||||
border: red 1px dashed;
|
||||
}
|
83
frontend-old-ember/app/styles/fonts.css
Normal file
83
frontend-old-ember/app/styles/fonts.css
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* Copied from: https://github.com/Vjecni/OpenDyslexic-Font/blob/main/opendyslexic.css */
|
||||
@font-face {
|
||||
font-family: OpenDyslexic;
|
||||
src: url("/assets/fonts/OpenDyslexic-Regular.eot");
|
||||
src:
|
||||
url("/assets/fonts/OpenDyslexic-Regular.eot?#iefix")
|
||||
format("embedded-opentype"),
|
||||
url("/assets/fonts/OpenDyslexic-Regular.woff2") format("woff2"),
|
||||
url("/assets/fonts/OpenDyslexic-Regular.woff") format("woff"),
|
||||
url("/assets/fonts/OpenDyslexic-Regular.otf") format("opentype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: OpenDyslexic;
|
||||
src: url("/assets/fonts/OpenDyslexic-Bold.eot");
|
||||
src:
|
||||
url("/assets/fonts/OpenDyslexic-Bold.eot?#iefix")
|
||||
format("embedded-opentype"),
|
||||
url("/assets/fonts/OpenDyslexic-Bold.woff2") format("woff2"),
|
||||
url("/assets/fonts/OpenDyslexic-Bold.woff") format("woff"),
|
||||
url("/assets/fonts/OpenDyslexic-Bold.otf") format("opentype");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: OpenDyslexic;
|
||||
src: url("/assets/fonts/OpenDyslexic-Italic.eot");
|
||||
src:
|
||||
url("/assets/fonts/OpenDyslexic-Italic.eot?#iefix")
|
||||
format("embedded-opentype"),
|
||||
url("/assets/fonts/OpenDyslexic-Italic.woff2") format("woff2"),
|
||||
url("/assets/fonts/OpenDyslexic-Italic.woff") format("woff"),
|
||||
url("/assets/fonts/OpenDyslexic-Italic.otf") format("opentype");
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: OpenDyslexic;
|
||||
src: url("/assets/fonts/OpenDyslexic-BoldItalic.eot");
|
||||
src:
|
||||
url("/assets/fonts/OpenDyslexic-BoldItalic.eot?#iefix")
|
||||
format("embedded-opentype"),
|
||||
url("/assets/fonts/OpenDyslexic-BoldItalic.woff2") format("woff2"),
|
||||
url("/assets/fonts/OpenDyslexic-BoldItalic.woff") format("woff"),
|
||||
url("/assets/fonts/OpenDyslexic-BoldItalic.otf") format("opentype");
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: OpenDyslexic, sans-serif;
|
||||
}
|
||||
|
||||
/* Apply OpenDyslexic Bold font to h1, h2, and h3 */
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
font-family: OpenDyslexic, sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Apply OpenDyslexic Normal weight to p, span, a, label, and li */
|
||||
p,
|
||||
span,
|
||||
a,
|
||||
label,
|
||||
li {
|
||||
font-family: OpenDyslexic, sans-serif;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* Apply OpenDyslexic Light weight to input, textarea, and button */
|
||||
input,
|
||||
textarea,
|
||||
button {
|
||||
font-family: OpenDyslexic, sans-serif;
|
||||
font-weight: 300; /* Light weight */
|
||||
}
|
136
frontend-old-ember/app/styles/notes.css
Normal file
136
frontend-old-ember/app/styles/notes.css
Normal file
|
@ -0,0 +1,136 @@
|
|||
.note {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
/* width: fit-content; */
|
||||
height: fit-content;
|
||||
|
||||
/* align-items: center; */
|
||||
|
||||
/* max-width: 50em; */
|
||||
padding: 0.5em;
|
||||
background-color: var(--background-100);
|
||||
color: var(--text);
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
.note-user-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 2px solid black;
|
||||
width: fit-content;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
.note-user-pfp {
|
||||
width: 3em;
|
||||
height: 3em;
|
||||
padding-bottom: 0.1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.note-user-name-and-handle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
/* align-items: center; */
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
.note-user-displayname {
|
||||
padding-top: 0.1em;
|
||||
margin: 0.1em;
|
||||
}
|
||||
|
||||
.note-user-handle {
|
||||
font-size: 0.8em;
|
||||
color: #555;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.note-timestamps-container {
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
|
||||
.note-timestamp {
|
||||
font-size: 0.8em;
|
||||
margin: -0.1em;
|
||||
color: var(--text-700);
|
||||
}
|
||||
|
||||
.note-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: fit-content;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.note-content-text {
|
||||
margin-top: -0.08em;
|
||||
margin-bottom: -0.08em;
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
.note-content-toggle {
|
||||
margin-top: 0.3em;
|
||||
margin-bottom: 0.3em;
|
||||
cursor: pointer;
|
||||
background-color: var(--secondary-300);
|
||||
padding: 0.1em 0.3em;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.note-content-toggle:hover {
|
||||
background-color: var(--secondary-200);
|
||||
}
|
||||
|
||||
.note-interactions-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
border-top: 1px solid var(--text-300);
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
|
||||
.note-interactions-interaction-button {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
border: 1px solid #aaa;
|
||||
padding-left: 0.6em;
|
||||
|
||||
/* padding-right: 0.6em; */
|
||||
border-radius: 8px;
|
||||
margin-right: 0.7em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.note-interactions-interaction-icon {
|
||||
height: 2.5ex;
|
||||
padding-right: 0.2em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.note-interactions-interaction-counter {
|
||||
font-weight: bold;
|
||||
padding: 0.3em;
|
||||
margin-top: -0.01em;
|
||||
margin-bottom: -0.01em;
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
.note-interactions-interactions-button-like {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.note-interactions-interactions-button-custom {
|
||||
align-items: center;
|
||||
border-left: 1px black solid;
|
||||
padding-top: 0.5em;
|
||||
padding-left: 0.4em;
|
||||
padding-right: 0.4em;
|
||||
}
|
4
frontend-old-ember/app/styles/svgs.css
Normal file
4
frontend-old-ember/app/styles/svgs.css
Normal file
|
@ -0,0 +1,4 @@
|
|||
.svg-black-white {
|
||||
fill: var(--text);
|
||||
stroke: var(--text);
|
||||
}
|
11
frontend-old-ember/app/styles/timeline.css
Normal file
11
frontend-old-ember/app/styles/timeline.css
Normal file
|
@ -0,0 +1,11 @@
|
|||
.timeline {
|
||||
max-width: 50%;
|
||||
width: fit-content;
|
||||
height: 100%;
|
||||
scroll-behavior: smooth;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.timeline-separator {
|
||||
color: var(--text-400);
|
||||
}
|
21
frontend-old-ember/app/styles/util.css
Normal file
21
frontend-old-ember/app/styles/util.css
Normal file
|
@ -0,0 +1,21 @@
|
|||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Copied from: https://stackoverflow.com/a/4407335 */
|
||||
.noselect {
|
||||
-webkit-touch-callout: none; /* iOS Safari */ /* Safari */ /* Konqueror HTML */ /* Old versions of Firefox */ /* Internet Explorer/Edge */
|
||||
user-select: none; /* Non-prefixed version, currently
|
||||
supported by Chrome, Edge, Opera and Firefox */
|
||||
}
|
||||
|
||||
.separator-horizontal {
|
||||
width: 100%;
|
||||
border: 1px solid black;
|
||||
margin-top: 0.2em;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
.filling-spacer {
|
||||
flex-grow: 1;
|
||||
}
|
43
frontend-old-ember/app/styles/util/mailEntry.css
Normal file
43
frontend-old-ember/app/styles/util/mailEntry.css
Normal file
|
@ -0,0 +1,43 @@
|
|||
.mail-entry {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.mail-input {
|
||||
outline: 0;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.mail-input-ok {
|
||||
border: 1px solid green;
|
||||
box-shadow: 0 0 5px green;
|
||||
}
|
||||
|
||||
.mail-input-error {
|
||||
border: 1px solid red;
|
||||
box-shadow: 0 0 5px red;
|
||||
}
|
||||
|
||||
.mail-status {
|
||||
/* margin: 0; */
|
||||
margin-top: 0.75em;
|
||||
margin-left: 0.4em;
|
||||
}
|
||||
|
||||
.mail-ok {
|
||||
color: green;
|
||||
|
||||
/* margin-top: -0.25lh; */
|
||||
|
||||
/* margin-bottom: -0.28lh; */
|
||||
font-size: 0.9lh;
|
||||
margin: 0;
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
|
||||
.mail-error {
|
||||
color: red;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0.6em;
|
||||
}
|
4
frontend-old-ember/app/styles/util/stringArray.css
Normal file
4
frontend-old-ember/app/styles/util/stringArray.css
Normal file
|
@ -0,0 +1,4 @@
|
|||
.string-array-element-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
2
frontend-old-ember/app/templates/about.hbs
Normal file
2
frontend-old-ember/app/templates/about.hbs
Normal file
|
@ -0,0 +1,2 @@
|
|||
{{page-title "About"}}
|
||||
{{outlet}}
|
2
frontend-old-ember/app/templates/application.hbs
Normal file
2
frontend-old-ember/app/templates/application.hbs
Normal file
|
@ -0,0 +1,2 @@
|
|||
{{page-title "FrontendReactive"}}
|
||||
{{outlet}}
|
2
frontend-old-ember/app/templates/auth.hbs
Normal file
2
frontend-old-ember/app/templates/auth.hbs
Normal file
|
@ -0,0 +1,2 @@
|
|||
{{page-title "Auth"}}
|
||||
<Auth::Login />
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue