uhh, lots of things in frontend

This commit is contained in:
Melody Becker 2024-09-19 13:50:04 +02:00
parent 76e8b183ca
commit 2d58312aa0
17 changed files with 30294 additions and 27939 deletions

View file

@ -0,0 +1,14 @@
<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="{{@displayname}}"
@handle="@{{@username}}@{{@serverdomain}}"
/>
<Note::Content @content="{{@content}}" />
<div class="note-timestamps-container">
<p class="note-timestamp" id="note-edited-timestamp">Edited: At some time in
the future</p>
<p class="note-timestamp" id="note-created-timestamp">Posted: Before the Big
Bang</p>
</div>
</div>

View file

@ -0,0 +1,26 @@
import { action } from '@ember/object';
import Component from '@glimmer/component';
export interface NoteSignature {
// The arguments accepted by the component
Args: {
isInTimeline: 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 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");
}
}
}

View 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}}
>Expand</div>
{{else}}
<div
type="button"
class="note-content-toggle"
{{on "click" this.collapse}}
>Collapse</div>
{{/if}}
{{/if}}
</div>

View file

@ -0,0 +1,57 @@
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;
};
// 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 '';
}
}

View file

@ -0,0 +1,9 @@
<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}}</p>
<p class="note-user-handle">{{@handle}}</p>
</div>
</div>

View file

@ -1,4 +0,0 @@
<div class="timeline-note">
<h3>{{@username}}</h3>
<p>{{@content}}</p>
</div>

View file

@ -1,6 +1,17 @@
/* Ember supports plain CSS out of the box. More info: https://cli.emberjs.com/release/advanced-use/stylesheets/ */ /* Ember supports plain CSS out of the box. More info: https://cli.emberjs.com/release/advanced-use/stylesheets/ */
@import url("notes.css");
.timeline-note { * {
display: flex; font-family:
flex-direction: column; system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
Oxygen,
Ubuntu,
Cantarell,
"Open Sans",
"Helvetica Neue",
sans-serif;
} }

View file

@ -0,0 +1,87 @@
.note {
display: flex;
flex-direction: column;
width: fit-content;
height: fit-content;
/* align-items: center; */
border: 1px dashed green;
max-width: 50em;
padding: 0.5em;
background-color: #eee;
}
.note-user-header {
display: flex;
flex-direction: row;
border: 2px solid black;
width: fit-content;
padding-right: 0.5em;
}
.note-user-pfp {
border: 1px dashed red;
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: 85%;
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: gray;
}
.note-content {
display: flex;
flex-direction: column;
width: fit-content;
align-items: center;
border: 1px dashed red;
}
.note-content-text {
border: 1px dashed red;
margin-top: -0.08em;
margin-bottom: -0.08em;
padding: 0.2em;
}
.note-content-toggle {
margin-top: 0.3em;
margin-bottom: 0.3em;
cursor: default;
background-color: #ccc;
padding: 0.1em 0.3em 0.2em;
border-radius: 8px;
border: 1px solid #aaa;
}
.note-content-toggle:hover {
background-color: #aaa;
}

View file

@ -1,4 +1,14 @@
{{page-title "FrontendReactive"}} {{page-title "FrontendReactive"}}
{{outlet}} {{outlet}}
<Timeline::Note @username="bob" @content="Hello world" /> <Note
@displayname="bob"
@username="alice"
@serverdomain="example.com"
@isInTimeline="false"
@content="Scuttle crack Jennys tea cup American Main lass Jolly Roger prow reef sails tackle ye Chain Shot. Cackle fruit topgallant draft bilge gangplank Jolly Roger ahoy holystone black jack aye. Mizzenmast stern warp Buccaneer Spanish Main Letter of Marque pink aft skysail grog blossom.
Crow's nest scuppers topgallant fore dance the hempen jig loot tack fluke squiffy flogging. Red ensign Letter of Marque poop deck scallywag chandler rutters sheet avast sloop to go on account. Spike loaded to the gunwalls prow smartly gabion heave down scallywag interloper chantey case shot.
Quarterdeck cackle fruit ballast lookout bounty jack trysail crow's nest hulk spyglass. Gabion gangplank long boat coffer ahoy wench parley American Main jack come about. Trysail code of conduct cable provost loaded to the gunwalls chase landlubber or just lubber gibbet gunwalls hempen halter."
/>

View file

@ -5,6 +5,9 @@ const EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function (defaults) { module.exports = function (defaults) {
const app = new EmberApp(defaults, { const app = new EmberApp(defaults, {
'ember-cli-babel': { enableTypeScriptTransform: true }, 'ember-cli-babel': { enableTypeScriptTransform: true },
minifyCSS: {
options: { processImport: true },
},
// Add options here // Add options here
}); });

File diff suppressed because it is too large Load diff

View file

@ -36,11 +36,6 @@
"@glint/template": "^1.4.0", "@glint/template": "^1.4.0",
"@tsconfig/ember": "^3.0.8", "@tsconfig/ember": "^3.0.8",
"@types/ember": "^4.0.11", "@types/ember": "^4.0.11",
"@types/ember-data": "^4.4.16",
"@types/ember-data__adapter": "^4.0.6",
"@types/ember-data__model": "^4.0.5",
"@types/ember-data__serializer": "^4.0.6",
"@types/ember-data__store": "^4.0.7",
"@types/ember__application": "^4.0.11", "@types/ember__application": "^4.0.11",
"@types/ember__array": "^4.0.10", "@types/ember__array": "^4.0.10",
"@types/ember__component": "^4.0.22", "@types/ember__component": "^4.0.22",
@ -61,6 +56,11 @@
"@types/ember__template": "^4.0.7", "@types/ember__template": "^4.0.7",
"@types/ember__test": "^4.0.6", "@types/ember__test": "^4.0.6",
"@types/ember__utils": "^4.0.7", "@types/ember__utils": "^4.0.7",
"@types/ember-data": "^4.4.16",
"@types/ember-data__adapter": "^4.0.6",
"@types/ember-data__model": "^4.0.5",
"@types/ember-data__serializer": "^4.0.6",
"@types/ember-data__store": "^4.0.7",
"@types/qunit": "^2.19.10", "@types/qunit": "^2.19.10",
"@types/rsvp": "^4.0.9", "@types/rsvp": "^4.0.9",
"@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/eslint-plugin": "^6.21.0",
@ -79,6 +79,7 @@
"ember-cli-terser": "^4.0.2", "ember-cli-terser": "^4.0.2",
"ember-data": "~5.3.8", "ember-data": "~5.3.8",
"ember-fetch": "^8.1.2", "ember-fetch": "^8.1.2",
"ember-infinity": "^3.0.0",
"ember-load-initializers": "^2.1.2", "ember-load-initializers": "^2.1.2",
"ember-modifier": "^4.2.0", "ember-modifier": "^4.2.0",
"ember-page-title": "^8.2.3", "ember-page-title": "^8.2.3",

View file

@ -0,0 +1,21 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "frontend-reactive/tests/helpers";
import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
module("Integration | Component | note", function(hooks) {
setupRenderingTest(hooks);
test("it renders", async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`
<Note @displayname="bob" @username="alice" @serverdomain="example.com" @content="some content"/>
`);
assert.dom("p.note-user-displayname").hasText("bob");
assert.dom("p.note-user-handle").hasText("@alice@example.com");
assert.dom("p.note-content-text").hasText("some content");
});
});

View file

@ -0,0 +1,20 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'frontend-reactive/tests/helpers';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | note/content', function (hooks) {
setupRenderingTest(hooks);
test('note-content', async function (assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
const shortContent = 'Lorem ipsum odor amet, consectetuer adipiscing elit.';
this.set('shortContent', shortContent);
await render(hbs`<Note::Content @content="{{this.shortContent}}"/>`);
assert.dom('.note-content-text').hasText(shortContent);
});
});

View file

@ -0,0 +1,20 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "frontend-reactive/tests/helpers";
import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
module("Integration | Component | note/user-header", function(hooks) {
setupRenderingTest(hooks);
test("it renders", async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(
hbs`<Note::UserHeader @displayname="bob" @handle="@alice@example.com"/>`,
);
assert.dom("p.note-user-displayname").hasText("bob");
assert.dom("p.note-user-handle").hasText("@alice@example.com");
});
});

View file

@ -1,25 +0,0 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "frontend-reactive/tests/helpers";
import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
module("Integration | Component | timeline/note", function (hooks) {
setupRenderingTest(hooks);
test("it renders", async function (assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`<Timeline::Note />`);
assert.dom().hasText("");
// Template block usage:
await render(hbs`
<Timeline::Note @username="bob" @content="some content"/>
`);
assert.dom("h3").hasText("bob");
assert.dom("p").hasText("some content");
});
});