Cleanup of review-css to use tailwind
This commit is contained in:
parent
9cb3a49b28
commit
a76d8822ff
7 changed files with 52 additions and 108 deletions
|
@ -12,7 +12,7 @@ import SingleReview from "./SingleReview";
|
||||||
export default class ReviewElement extends UIElement {
|
export default class ReviewElement extends UIElement {
|
||||||
private readonly _reviews: UIEventSource<Review[]>;
|
private readonly _reviews: UIEventSource<Review[]>;
|
||||||
private readonly _subject: string;
|
private readonly _subject: string;
|
||||||
private _middleElement: UIElement;
|
private readonly _middleElement: UIElement;
|
||||||
|
|
||||||
constructor(subject: string, reviews: UIEventSource<Review[]>, middleElement: UIElement) {
|
constructor(subject: string, reviews: UIEventSource<Review[]>, middleElement: UIElement) {
|
||||||
super(reviews);
|
super(reviews);
|
||||||
|
@ -34,7 +34,7 @@ export default class ReviewElement extends UIElement {
|
||||||
const avg = (revs.map(review => review.rating).reduce((a, b) => a + b, 0) / revs.length);
|
const avg = (revs.map(review => review.rating).reduce((a, b) => a + b, 0) / revs.length);
|
||||||
elements.push(
|
elements.push(
|
||||||
new Combine([
|
new Combine([
|
||||||
SingleReview.GenStars(avg).SetClass("stars flex"),
|
SingleReview.GenStars(avg),
|
||||||
`<a target="_blank" href='https://mangrove.reviews/search?sub=${encodeURIComponent(this._subject)}'>`,
|
`<a target="_blank" href='https://mangrove.reviews/search?sub=${encodeURIComponent(this._subject)}'>`,
|
||||||
revs.length === 1 ? Translations.t.reviews.title_singular :
|
revs.length === 1 ? Translations.t.reviews.title_singular :
|
||||||
Translations.t.reviews.title
|
Translations.t.reviews.title
|
||||||
|
@ -43,7 +43,7 @@ export default class ReviewElement extends UIElement {
|
||||||
"</a>"
|
"</a>"
|
||||||
])
|
])
|
||||||
|
|
||||||
.SetClass("review-title"));
|
.SetClass("font-2xl flex justify-between items-center pl-2 pr-2"));
|
||||||
|
|
||||||
elements.push(this._middleElement);
|
elements.push(this._middleElement);
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ export default class ReviewElement extends UIElement {
|
||||||
|
|
||||||
.SetClass("review-attribution"))
|
.SetClass("review-attribution"))
|
||||||
|
|
||||||
return new Combine(elements).SetClass("review").Render();
|
return new Combine(elements).SetClass("block").Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -56,7 +56,7 @@ export default class ReviewForm extends InputElement<Review> {
|
||||||
onSave(this._value.data, () => {
|
onSave(this._value.data, () => {
|
||||||
self._saveButton = Translations.t.reviews.saved.SetClass("thanks");
|
self._saveButton = Translations.t.reviews.saved.SetClass("thanks");
|
||||||
});
|
});
|
||||||
})
|
}).SetClass("break-normal")
|
||||||
|
|
||||||
this._isAffiliated = new CheckBoxes([t.i_am_affiliated])
|
this._isAffiliated = new CheckBoxes([t.i_am_affiliated])
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,9 @@ export default class SingleReview extends UIElement{
|
||||||
}
|
}
|
||||||
const scoreTen = Math.round(rating / 10);
|
const scoreTen = Math.round(rating / 10);
|
||||||
return new Combine([
|
return new Combine([
|
||||||
"<img src='./assets/svg/star.svg' />".repeat(Math.floor(scoreTen / 2)),
|
"<img src='./assets/svg/star.svg' class='h-8 md:h-12'/>".repeat(Math.floor(scoreTen / 2)),
|
||||||
scoreTen % 2 == 1 ? "<img src='./assets/svg/star_half.svg' />" : ""
|
scoreTen % 2 == 1 ? "<img src='./assets/svg/star_half.svg' class='h-8 md:h-12'/>" : ""
|
||||||
])
|
]).SetClass("flex w-max")
|
||||||
}
|
}
|
||||||
InnerRender(): string {
|
InnerRender(): string {
|
||||||
const d = this._review.date;
|
const d = this._review.date;
|
||||||
|
@ -33,25 +33,23 @@ export default class SingleReview extends UIElement{
|
||||||
[
|
[
|
||||||
new Combine([
|
new Combine([
|
||||||
SingleReview.GenStars(review.rating)
|
SingleReview.GenStars(review.rating)
|
||||||
.SetClass("review-rating"),
|
]),
|
||||||
new FixedUiElement(review.comment).SetClass("review-comment")
|
new FixedUiElement(review.comment),
|
||||||
]).SetClass("review-stars-comment"),
|
|
||||||
|
|
||||||
new Combine([
|
new Combine([
|
||||||
new Combine([
|
new Combine([
|
||||||
|
|
||||||
new FixedUiElement(review.author).SetClass("review-author"),
|
new Combine(["<b>",review.author,"</b>"]),
|
||||||
review.affiliated ? Translations.t.reviews.affiliated_reviewer_warning : "",
|
review.affiliated ? Translations.t.reviews.affiliated_reviewer_warning : "",
|
||||||
]).SetStyle("margin-right: 0.5em"),
|
]).SetStyle("margin-right: 0.5em"),
|
||||||
new FixedUiElement(`${d.getFullYear()}-${Utils.TwoDigits(d.getMonth() + 1)}-${Utils.TwoDigits(d.getDate())} ${Utils.TwoDigits(d.getHours())}:${Utils.TwoDigits(d.getMinutes())}`)
|
new FixedUiElement(`${d.getFullYear()}-${Utils.TwoDigits(d.getMonth() + 1)}-${Utils.TwoDigits(d.getDate())} ${Utils.TwoDigits(d.getHours())}:${Utils.TwoDigits(d.getMinutes())}`)
|
||||||
.SetClass("review-date")
|
.SetClass("subtle-lighter")
|
||||||
]).SetClass("review-author-date")
|
]).SetClass("flex mb-4 justify-end")
|
||||||
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
el.SetClass("review-element");
|
el.SetClass("block p-2 m-1 rounded-xl subtle-background review-element");
|
||||||
if(review.made_by_user){
|
if(review.made_by_user.data){
|
||||||
el.SetClass("review-by-current-user")
|
el.SetClass("border-attention-catch")
|
||||||
}
|
}
|
||||||
return el.Render();
|
return el.Render();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ export default class SpecialVisualizations {
|
||||||
|
|
||||||
public static specialVisualizations: {
|
public static specialVisualizations: {
|
||||||
funcName: string,
|
funcName: string,
|
||||||
constr: ((state: State,tagSource: UIEventSource<any>, argument: string[]) => UIElement),
|
constr: ((state: State, tagSource: UIEventSource<any>, argument: string[]) => UIElement),
|
||||||
docs: string,
|
docs: string,
|
||||||
example?: string,
|
example?: string,
|
||||||
args: { name: string, defaultValue?: string, doc: string }[]
|
args: { name: string, defaultValue?: string, doc: string }[]
|
||||||
|
@ -32,7 +32,7 @@ export default class SpecialVisualizations {
|
||||||
funcName: "all_tags",
|
funcName: "all_tags",
|
||||||
docs: "Prints all key-value pairs of the object - used for debugging",
|
docs: "Prints all key-value pairs of the object - used for debugging",
|
||||||
args: [],
|
args: [],
|
||||||
constr: ((state: State,tags: UIEventSource<any>) => {
|
constr: ((state: State, tags: UIEventSource<any>) => {
|
||||||
return new VariableUiElement(tags.map(tags => {
|
return new VariableUiElement(tags.map(tags => {
|
||||||
const parts = [];
|
const parts = [];
|
||||||
for (const key in tags) {
|
for (const key in tags) {
|
||||||
|
@ -56,10 +56,10 @@ export default class SpecialVisualizations {
|
||||||
defaultValue: "true",
|
defaultValue: "true",
|
||||||
doc: "Also include images given via 'Wikidata', 'wikimedia_commons' and 'mapillary"
|
doc: "Also include images given via 'Wikidata', 'wikimedia_commons' and 'mapillary"
|
||||||
}],
|
}],
|
||||||
constr: (state: State,tags, args) => {
|
constr: (state: State, tags, args) => {
|
||||||
const imagePrefix = args[0];
|
const imagePrefix = args[0];
|
||||||
const loadSpecial = args[1].toLowerCase() === "true";
|
const loadSpecial = args[1].toLowerCase() === "true";
|
||||||
const searcher : UIEventSource<{ key: string, url: string }[]> = new ImageSearcher(tags, imagePrefix, loadSpecial);
|
const searcher: UIEventSource<{ key: string, url: string }[]> = new ImageSearcher(tags, imagePrefix, loadSpecial);
|
||||||
|
|
||||||
return new ImageCarousel(searcher, tags);
|
return new ImageCarousel(searcher, tags);
|
||||||
}
|
}
|
||||||
|
@ -73,25 +73,28 @@ export default class SpecialVisualizations {
|
||||||
doc: "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)",
|
doc: "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)",
|
||||||
defaultValue: "image"
|
defaultValue: "image"
|
||||||
}],
|
}],
|
||||||
constr: (state: State,tags, args) => {
|
constr: (state: State, tags, args) => {
|
||||||
return new ImageUploadFlow(tags, args[0])
|
return new ImageUploadFlow(tags, args[0])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
funcName: "reviews",
|
funcName: "reviews",
|
||||||
docs: "Adds an overview of the mangrove-reviews of this object. IMPORTANT: the _name_ of the object should be defined for this to work!",
|
docs: "Adds an overview of the mangrove-reviews of this object. Mangrove.Reviews needs - in order to identify the reviewed object - a coordinate and a name. By default, the name of the object is given, but this can be overwritten",
|
||||||
|
example: "<b>{reviews()}<b> for a vanilla review, <b>{reviews(name, play_forest)}</b> to review a play forest. If a name is known, the name will be used as identifier, otherwise 'play_forest' is used",
|
||||||
args: [{
|
args: [{
|
||||||
name: "subject",
|
name: "subjectKey",
|
||||||
doc: "The identifier used for this value; by default the name of the reviewed object"
|
defaultValue: "name",
|
||||||
|
doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>"
|
||||||
|
}, {
|
||||||
|
name: "fallback",
|
||||||
|
doc: "The identifier to use, if <i>tags[subjectKey]</i> as specified above is not available. This is effectively a fallback value"
|
||||||
}],
|
}],
|
||||||
constr: (state: State,tags, args) => {
|
constr: (state: State, tags, args) => {
|
||||||
const tgs = tags.data;
|
const tgs = tags.data;
|
||||||
let subject = tgs.name ?? "";
|
const key = args[0] ?? "name"
|
||||||
if (args[0] !== undefined && args[0] !== "") {
|
let subject = tgs[key] ?? args[1];
|
||||||
subject = args[0];
|
if (subject === undefined || subject === "") {
|
||||||
}
|
|
||||||
if (subject === "") {
|
|
||||||
return Translations.t.reviews.name_required;
|
return Translations.t.reviews.name_required;
|
||||||
}
|
}
|
||||||
const mangrove = MangroveReviews.Get(Number(tgs._lon), Number(tgs._lat),
|
const mangrove = MangroveReviews.Get(Number(tgs._lon), Number(tgs._lat),
|
||||||
|
@ -111,7 +114,7 @@ export default class SpecialVisualizations {
|
||||||
defaultValue: "opening_hours",
|
defaultValue: "opening_hours",
|
||||||
doc: "The tagkey from which the table is constructed."
|
doc: "The tagkey from which the table is constructed."
|
||||||
}],
|
}],
|
||||||
constr: (state: State,tagSource: UIEventSource<any>, args) => {
|
constr: (state: State, tagSource: UIEventSource<any>, args) => {
|
||||||
let keyname = args[0];
|
let keyname = args[0];
|
||||||
if (keyname === undefined || keyname === "") {
|
if (keyname === undefined || keyname === "") {
|
||||||
keyname = keyname ?? "opening_hours"
|
keyname = keyname ?? "opening_hours"
|
||||||
|
@ -132,7 +135,7 @@ export default class SpecialVisualizations {
|
||||||
}, {
|
}, {
|
||||||
name: "path", doc: "The path (or shorthand) that should be returned"
|
name: "path", doc: "The path (or shorthand) that should be returned"
|
||||||
}],
|
}],
|
||||||
constr: (state: State,tagSource: UIEventSource<any>, args) => {
|
constr: (state: State, tagSource: UIEventSource<any>, args) => {
|
||||||
const url = args[0];
|
const url = args[0];
|
||||||
const shorthands = args[1];
|
const shorthands = args[1];
|
||||||
const neededValue = args[2];
|
const neededValue = args[2];
|
||||||
|
@ -147,10 +150,10 @@ export default class SpecialVisualizations {
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
name: "url",
|
name: "url",
|
||||||
doc: "The url to share (defualt: current URL)",
|
doc: "The url to share (default: current URL)",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
constr: (state: State,tagSource: UIEventSource<any>, args) => {
|
constr: (state: State, tagSource: UIEventSource<any>, args) => {
|
||||||
if (window.navigator.share) {
|
if (window.navigator.share) {
|
||||||
const title = state.layoutToUse.data.title.txt;
|
const title = state.layoutToUse.data.title.txt;
|
||||||
let name = tagSource.data.name;
|
let name = tagSource.data.name;
|
||||||
|
@ -204,7 +207,9 @@ export default class SpecialVisualizations {
|
||||||
|
|
||||||
|
|
||||||
return new Combine([
|
return new Combine([
|
||||||
|
"<h3>Special tag renderings</h3>",
|
||||||
"In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and visualizations to be reused by custom themes or even to query third-party API's.",
|
"In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and visualizations to be reused by custom themes or even to query third-party API's.",
|
||||||
|
"General usage is <b>{func_name()}</b> or <b>{func_name(arg, someotherarg)}</b>. Note that you <i>do not</i> need to use quotes around your arguments, the comma is enough to seperate them. This also implies you cannot use a comma in your args",
|
||||||
...helpTexts
|
...helpTexts
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -18,19 +18,19 @@ export default class Translations {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static T(t: string | any): Translation {
|
static T(t: string | any, context = undefined): Translation {
|
||||||
if(t === undefined){
|
if(t === undefined){
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if(typeof t === "string"){
|
if(typeof t === "string"){
|
||||||
return new Translation({"*":t});
|
return new Translation({"*":t}, context);
|
||||||
}
|
}
|
||||||
if(t.render !== undefined){
|
if(t.render !== undefined){
|
||||||
const msg = "Creating a translation, but this object contains a 'render'-field. Use the translation directly"
|
const msg = "Creating a translation, but this object contains a 'render'-field. Use the translation directly"
|
||||||
console.error(msg, t);
|
console.error(msg, t);
|
||||||
throw msg
|
throw msg
|
||||||
}
|
}
|
||||||
return new Translation(t);
|
return new Translation(t, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static wtcache = {}
|
private static wtcache = {}
|
||||||
|
|
|
@ -1,70 +1,3 @@
|
||||||
.review {
|
|
||||||
display: block;
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-title {
|
|
||||||
font-size: x-large;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding-left: 1em;
|
|
||||||
padding-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-title img {
|
|
||||||
max-width: 1.5em;
|
|
||||||
height: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.review-rating img {
|
|
||||||
max-width: 1em;
|
|
||||||
height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-by-current-user {
|
|
||||||
border: 5px solid var(--catch-detail-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-rating {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 5em;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-date {
|
|
||||||
color: var(--subtle-detail-color-light-contrast);
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-stars-comment {
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.review-author {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-author-date {
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.review-element {
|
|
||||||
padding: 1em;
|
|
||||||
margin: 0.5em;
|
|
||||||
display: block;
|
|
||||||
border-radius: 1em;
|
|
||||||
background-color: var(--subtle-detail-color);
|
|
||||||
color: var(--subtle-detail-color-contrast);
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-attribution {
|
.review-attribution {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -110,7 +110,15 @@ a {
|
||||||
|
|
||||||
.subtle-background {
|
.subtle-background {
|
||||||
background: var(--subtle-detail-color);
|
background: var(--subtle-detail-color);
|
||||||
|
color: var(--subtle-detail-color-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.subtle-lighter {
|
||||||
|
color: var(--subtle-detail-color-light-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-attention-catch{ border: 5px solid var(--catch-detail-color);}
|
||||||
|
|
||||||
.slick-prev:before, .slick-next:before {
|
.slick-prev:before, .slick-next:before {
|
||||||
/*Slideshow workaround*/
|
/*Slideshow workaround*/
|
||||||
color:black !important;
|
color:black !important;
|
||||||
|
|
Loading…
Reference in a new issue