Skip to content

Commit

Permalink
Implenenting groupped markdowns #711
Browse files Browse the repository at this point in the history
  • Loading branch information
bpatrik committed Sep 3, 2023
1 parent 5a852dc commit ed56de4
Show file tree
Hide file tree
Showing 24 changed files with 492 additions and 310 deletions.
7 changes: 7 additions & 0 deletions demo/images/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,11 @@ Start numbering with offset:
57. foo
1. bar

<!-- @pg-date 2015-06-12 -->
## Day 1

You can tag section in the `*.md` files with `<!-- @pg-date <ISO_DATE> -->`, like: `<!-- @pg-date 2015-06-12 -->` to attach them to a date.
Then if you group by date, they will show up at the assigned day.

That mart of the markdown will be removed from the mail markdown at the top and shown only at that day.

20 changes: 20 additions & 0 deletions src/common/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,26 @@ export class Utils {
return true;
}

static toIsoString(d: number | Date) {
if (!(d instanceof Date)) {
d = new Date(d);
}
return d.getUTCFullYear() + '-' + d.getUTCMonth() + '-' + d.getUTCDate();
}


static makeUTCMidnight(d: number | Date) {
if (!(d instanceof Date)) {
d = new Date(d);
}
d.setUTCHours(0);
d.setUTCMinutes(0);
d.setUTCSeconds(0);
d.setUTCMilliseconds(0);

return d;
}

static renderDataSize(size: number): string {
const postFixes = ['B', 'KB', 'MB', 'GB', 'TB'];
let index = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/frontend/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ import {ParseIntPipe} from './pipes/ParseIntPipe';
import {
SortingMethodSettingsEntryComponent
} from './ui/settings/template/settings-entry/sorting-method/sorting-method.settings-entry.component';
import {ContentLoaderService} from './ui/gallery/contentLoader.service';

@Injectable()
export class MyHammerConfig extends HammerGestureConfig {
Expand Down Expand Up @@ -344,6 +345,7 @@ Marker.prototype.options.icon = MarkerFactory.defIcon;
AlbumsService,
GalleryCacheService,
ContentService,
ContentLoaderService,
FilterService,
GallerySortingService,
MapService,
Expand Down
24 changes: 11 additions & 13 deletions src/frontend/app/model/query.service.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { Injectable } from '@angular/core';
import { ShareService } from '../ui/gallery/share.service';
import { MediaDTO } from '../../../common/entities/MediaDTO';
import { QueryParams } from '../../../common/QueryParams';
import { Utils } from '../../../common/Utils';
import { ContentService } from '../ui/gallery/content.service';
import { Config } from '../../../common/config/public/Config';
import {
ParentDirectoryDTO,
SubDirectoryDTO,
} from '../../../common/entities/DirectoryDTO';
import {Injectable} from '@angular/core';
import {ShareService} from '../ui/gallery/share.service';
import {MediaDTO} from '../../../common/entities/MediaDTO';
import {QueryParams} from '../../../common/QueryParams';
import {Utils} from '../../../common/Utils';
import {Config} from '../../../common/config/public/Config';
import {ParentDirectoryDTO, SubDirectoryDTO,} from '../../../common/entities/DirectoryDTO';
import {ContentLoaderService} from '../ui/gallery/contentLoader.service';

@Injectable()
export class QueryService {
constructor(
private shareService: ShareService,
private galleryService: ContentService
) {}
private galleryService: ContentLoaderService
) {
}

getMediaStringId(media: MediaDTO): string {
if (this.galleryService.isSearchResult()) {
Expand Down
17 changes: 17 additions & 0 deletions src/frontend/app/ui/gallery/blog/blog.gallery.component.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
.btn-blog-details {
position: absolute;
bottom: 0;
border: 0;
width: 100%;
}

.btn-blog-details:hover {
background-image: linear-gradient(transparent, rgba(var(--bs-body-color-rgb), 0.5));
}

.blog {
opacity: 0.8;
position: relative;
}

.blog:hover {
opacity: 1;
}

.card-body {
Expand Down
37 changes: 23 additions & 14 deletions src/frontend/app/ui/gallery/blog/blog.gallery.component.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
<div class="blog">
<div class="card">
<div class="card-body" style="min-height: 77px" [style.height]="collapsed ? '77px':''">
<ng-container *ngFor="let md of markdowns; let i = index">
<markdown
*ngIf="!collapsed"
[data]="md">
</markdown>
<span *ngIf="collapsed" class="text-preview">
{{md}}
</span>
<hr *ngIf="i != markdowns.length-1">
</ng-container>
<ng-container *ngIf="mkObservable | async as markdowns">
<div class="blog" *ngIf="markdowns.length > 0">
<div class="card">
<div class="card-body" style="min-height: 77px" [style.height]="!open ? '77px':''">
<ng-container *ngFor="let md of markdowns; let last = last">
<markdown
*ngIf="open"
[data]="md.text">
</markdown>
<span *ngIf="!open" class="text-preview">
<markdown
[inline]="true"
[data]="md.text">
</markdown>
</span>
<hr *ngIf="!last">
</ng-container>
</div>
</div>

<button class="btn btn-blog-details text-body" (click)="toggleCollapsed()">
<ng-icon [name]="open ? 'ionChevronUpOutline' : 'ionChevronDownOutline'"></ng-icon>
</button>
</div>
</div>
</ng-container>
37 changes: 23 additions & 14 deletions src/frontend/app/ui/gallery/blog/blog.gallery.component.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
import { Component, Input } from '@angular/core';
import { FileDTO } from '../../../../../common/entities/FileDTO';
import { BlogService } from './blog.service';
import { OnChanges } from '../../../../../../node_modules/@angular/core';
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {BlogService, GroupedMarkdown} from './blog.service';
import {OnChanges} from '../../../../../../node_modules/@angular/core';
import {Utils} from '../../../../../common/Utils';
import {map, Observable} from 'rxjs';

@Component({
selector: 'app-gallery-blog',
templateUrl: './blog.gallery.component.html',
styleUrls: ['./blog.gallery.component.css'],
})
export class GalleryBlogComponent implements OnChanges {
@Input() mdFiles: FileDTO[];
@Input() collapsed: boolean;
markdowns: string[] = [];
@Input() open: boolean;
@Input() date: Date;
@Output() openChange = new EventEmitter<boolean>();
public markdowns: string[] = [];
mkObservable: Observable<GroupedMarkdown[]>;

constructor(public blogService: BlogService) {}
constructor(public blogService: BlogService) {
}


ngOnChanges(): void {
this.loadMarkdown().catch(console.error);
const utcDate = this.date ? this.date.getTime() : undefined;
this.mkObservable = this.blogService.groupedMarkdowns.pipe(map(gm => {
if (!this.date) {
return gm.filter(g => !g.date);
}
return gm.filter(g => g.date == utcDate);
}));
}

async loadMarkdown(): Promise<void> {
this.markdowns = [];
for (const f of this.mdFiles) {
this.markdowns.push(await this.blogService.getMarkDown(f));
}

toggleCollapsed(): void {
this.open = !this.open;
this.openChange.emit(this.open);
}
}

97 changes: 92 additions & 5 deletions src/frontend/app/ui/gallery/blog/blog.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,94 @@
import { Injectable } from '@angular/core';
import { NetworkService } from '../../../model/network/network.service';
import { FileDTO } from '../../../../../common/entities/FileDTO';
import { Utils } from '../../../../../common/Utils';
import {Injectable} from '@angular/core';
import {NetworkService} from '../../../model/network/network.service';
import {FileDTO} from '../../../../../common/entities/FileDTO';
import {Utils} from '../../../../../common/Utils';
import {ContentService} from '../content.service';
import {mergeMap, Observable} from 'rxjs';
import {MDFilesFilterPipe} from '../../../pipes/MDFilesFilterPipe';

@Injectable()
export class BlogService {
cache: { [key: string]: Promise<string> | string } = {};
public groupedMarkdowns: Observable<GroupedMarkdown[]>;

constructor(private networkService: NetworkService) {}
constructor(private networkService: NetworkService,
private galleryService: ContentService,
private mdFilesFilterPipe: MDFilesFilterPipe) {

this.groupedMarkdowns = this.galleryService.sortedFilteredContent.pipe(
mergeMap(async content => {
if (!content) {
return [];
}
const dates = content.mediaGroups.map(g => g.date)
.filter(d => !!d).map(d => d.getTime());

const files = this.mdFilesFilterPipe.transform(content.metaFile)
.map(f => this.splitMarkDown(f, dates));

return (await Promise.all(files)).flat();
}));
}

private async splitMarkDown(file: FileDTO, dates: number[]): Promise<GroupedMarkdown[]> {
const markdown = await this.getMarkDown(file);

if (dates.length == 0) {
return [{
text: markdown,
file: file
}];
}

dates.sort();

const splitterRgx = new RegExp(/<!--\s*@pg-date:?\s*\d{4}-\d{1,2}-\d{1,2}\s*-->/, 'gi');
const dateRgx = new RegExp(/\d{4}-\d{1,2}-\d{1,2}/);

const ret: GroupedMarkdown[] = [];
const matches = Array.from(markdown.matchAll(splitterRgx));

if (matches.length == 0) {
return [{
text: markdown,
file: file
}];
}

ret.push({
text: markdown.substring(0, matches[0].index),
file: file
});


for (let i = 0; i < matches.length; ++i) {
const matchedStr = matches[i][0];
// get UTC midnight date
const dateNum = Utils.makeUTCMidnight(new Date(matchedStr.match(dateRgx)[0])).getTime();

let groupDate = dates.find((d, i) => i > dates.length - 1 ? false : dates[i + 1] > dateNum); //dates are sorted

// cant find the date. put to the last group (as it was later)
if (groupDate === undefined) {
groupDate = dates[dates.length - 1];
}
const text = i + 1 >= matches.length ? markdown.substring(matches[i].index) : markdown.substring(matches[i].index, matches[i + 1].index);

// if it would be in the same group. Concatenate it
const sameGroup = ret.find(g => g.date == groupDate);
if (sameGroup) {
sameGroup.text += text;
continue;
}
ret.push({
date: groupDate,
text: text,
file: file
});
}

return ret;
}

public getMarkDown(file: FileDTO): Promise<string> {
const filePath = Utils.concatUrls(
Expand All @@ -27,3 +108,9 @@ export class BlogService {
}
}


export interface GroupedMarkdown {
date?: number;
text: string;
file: FileDTO;
}
2 changes: 1 addition & 1 deletion src/frontend/app/ui/gallery/cache.gallery.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {GroupingMethod, SortingMethod} from '../../../../common/entities/Sorting
import {VersionService} from '../../model/version.service';
import {SearchQueryDTO, SearchQueryTypes,} from '../../../../common/entities/SearchQueryDTO';
import {ContentWrapper} from '../../../../common/entities/ConentWrapper';
import {ContentWrapperWithError} from './content.service';
import {ContentWrapperWithError} from './contentLoader.service';
import {ThemeModes} from '../../../../common/config/public/ClientConfig';

interface CacheItem<T> {
Expand Down
Loading

0 comments on commit ed56de4

Please sign in to comment.