diff --git a/src/app/components/home/home.component.ts b/src/app/components/home/home.component.ts index 4c103f2..4c864af 100644 --- a/src/app/components/home/home.component.ts +++ b/src/app/components/home/home.component.ts @@ -12,8 +12,6 @@ export class HomeComponent implements OnInit { constructor(private route: ActivatedRoute, private stateService: StateService) { } ngOnInit() { - // fix up the language, fetch it from the route! - this.stateService.getLanguageFromRoute(this.route.parent).subscribe(language => {console.log('homecomp gets: ' + language); }); } } diff --git a/src/app/components/languagetoggle/languagetoggle.component.ts b/src/app/components/languagetoggle/languagetoggle.component.ts index 7c3bfa7..1e70e33 100644 --- a/src/app/components/languagetoggle/languagetoggle.component.ts +++ b/src/app/components/languagetoggle/languagetoggle.component.ts @@ -1,5 +1,5 @@ import {Component, Input, OnInit} from '@angular/core'; -import {ActivatedRoute} from '@angular/router'; +import {ActivatedRoute, NavigationEnd, Router} from '@angular/router'; import {StateService} from '../../services/state.service'; @Component({ @@ -21,36 +21,31 @@ export class LanguagetoggleComponent implements OnInit { */ private show = false; - constructor(private route: ActivatedRoute, private stateService: StateService) { + constructor(private router: Router, private route: ActivatedRoute, private stateService: StateService) { } ngOnInit() { - this.stateService.getLanguageFromRoute(this.route).subscribe(lang => { - if(lang==null) { - console.log('language is null from first level route, ignoring'); - return; - } - console.log('languagetoggle gets first level lang: '+lang); - if (lang === this.language) { - console.log('equalled (first level of route)! showing the component' + this.language); - this.show = true; - } else { - this.show = false; - } - }); - this.stateService.getLanguageFromRoute(this.route.parent).subscribe(lang => { - if(lang==null) { - console.log('language is null from parent level route, ignoring'); - return; - } - console.log('languagetoggle gets parent level lang: '+lang); - if (lang === this.language) { - console.log('equalled (parent level of route)! showing the component ' + this.language); - this.show = true; - } else { - this.show = false; - } + this.route.pathFromRoot.forEach(p => { + this.router.events.filter(e => e instanceof NavigationEnd).subscribe(e => { + console.log('language toggle is detecting a navigation end: have to update values, things might have changed!'); + this.updateValues(); + }); }); } + private updateValues() { + const lang = this.stateService.getLanguage(); + if (lang == null) { + console.log('languagetoggle: language is null from stateservice, ignoring'); + return; + } + console.log('languagetoggle gets lang: ' + lang); + if (lang === this.language) { + console.log('languagetoggle: showing the component ' + lang); + this.show = true; + } else { + this.show = false; + } + } + } diff --git a/src/app/components/post/post.component.html b/src/app/components/post/post.component.html index 5cc6756..b088c38 100644 --- a/src/app/components/post/post.component.html +++ b/src/app/components/post/post.component.html @@ -4,7 +4,7 @@ {{post.created_timestamp | simpledate}}
- {{post.title}} + {{getPostTitle()}}
diff --git a/src/app/components/post/post.component.ts b/src/app/components/post/post.component.ts index af43588..ef3487b 100644 --- a/src/app/components/post/post.component.ts +++ b/src/app/components/post/post.component.ts @@ -13,19 +13,19 @@ export class PostComponent implements OnInit { @Input() post: Post; @ViewChild('htmlcontainer') htmlContainer: ElementRef; - constructor(private dataloaderService: DataloaderService, private stateService:StateService) { } + constructor(private dataloaderService: DataloaderService, private stateService: StateService) { } ngOnInit() { // TODO load the relevant HTML file! // console.log('post component has inited: '+this.post.id); // console.log(this.post); - //console.log('PostComponent is loading: '+this.post.id); - //console.log(this.post); + // console.log('PostComponent is loading: '+this.post.id); + // console.log(this.post); - this.dataloaderService.getPost(this.post.id).subscribe(content => { - //console.log('PostComponent got content for '+this.post.id); - //this is not the cause of the memory leak:\ + this.dataloaderService.getFullHtml(this.post, this.stateService.getLanguage()).subscribe(content => { + // console.log('PostComponent got content for '+this.post.id); + // this is not the cause of the memory leak:\ this.htmlContainer.nativeElement.innerHTML = content; }); @@ -35,4 +35,8 @@ export class PostComponent implements OnInit { isActiveTag(tag:string):boolean { return this.stateService.isActiveTag(tag); } + + getPostTitle() { + return this.post.title[this.stateService.getLanguage()]; + } } diff --git a/src/app/components/posts/posts.component.ts b/src/app/components/posts/posts.component.ts index 9bb11af..4979c3b 100644 --- a/src/app/components/posts/posts.component.ts +++ b/src/app/components/posts/posts.component.ts @@ -1,7 +1,7 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; -import { DataloaderService } from 'app/services/dataloader.service'; +import {DataloaderService} from 'app/services/dataloader.service'; import {StateService} from '../../services/state.service'; -import { Post } from '../../model/post'; +import {Post} from '../../model/post'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/merge'; @@ -16,53 +16,66 @@ import 'rxjs/add/operator/distinct'; }) export class PostsComponent implements OnInit, OnDestroy { + posts: Post[]; + tags = new Array(); + + constructor(private dataloaderService: DataloaderService, private stateService: StateService) { + } + ngOnDestroy(): void { - console.log('PostsComponent.ngOnDestroy called'); + // console.log('PostsComponent.ngOnDestroy called'); } - posts:Post[]; - tags = new Array(); - - constructor(private dataloaderService:DataloaderService, private stateService:StateService) { } - ngOnInit() { - console.log('PostsComponent ngOnInit()'); - //fetch the posts - let posts2 = this.dataloaderService.getPosts(); - //subscribing means big fat memory leak - //TODO fix this!!! + // console.log('PostsComponent ngOnInit()'); + // fetch the posts + const posts2 = this.dataloaderService.getPosts(); + // subscribing means big fat memory leak + // TODO fix this!!! posts2.subscribe(p => { this.posts = p; //figure out the different tags so we can filter on them - let temptags = new Array(); - this.posts.forEach(p=>p.tags.forEach(t=>temptags.push(t))); + const temptags = new Array(); + this.posts.forEach(p => p.tags.forEach(t => temptags.push(t))); console.log(temptags); //copy the temptags into the tags array, don't include duplicates - temptags.forEach(tt=> { - if(this.tags.indexOf(tt)==-1) + temptags.forEach(tt => { + if (this.tags.indexOf(tt) == -1) { this.tags.push(tt) + } }); //sort the array - this.tags.sort((a,b)=>a.localeCompare(b)); + this.tags.sort((a, b) => a.localeCompare(b)); }); console.log('PostsComponent ngOnInit() is done'); } - filterOnType(type:String): void { + filterOnType(type: String): void { } - postsToDisplay():Post[] { + postsToDisplay(): Post[] { //console.log('postsToDisplay called'); - let res = new Array(); - if(this.posts == null) + const res = new Array(); + if (this.posts == null) { return res; - for(let post of this.posts) { - if(this.stateService.shouldDisplay(post)) - res.push(post); } + for (const post of this.posts) { + // console.log(post); + if (this.stateService.shouldDisplay(post)) { + // console.log('we should display this'); + // also check the language! + // console.log(post.languages + ' ' + this.stateService.getLanguage()); + if (post.languages !== undefined && post.languages.indexOf(this.stateService.getLanguage()) >= 0) { + res.push(post); + } + } else { + // console.log('we should not display this'); + } + } + //console.log('displaying: '+res.length); return res; } @@ -72,7 +85,8 @@ export class PostsComponent implements OnInit, OnDestroy { this.stateService.toggleTag(tag); } - isActiveTag(tag: string) : boolean { + isActiveTag(tag: string): boolean { return this.stateService.isActiveTag(tag); } + } diff --git a/src/app/components/root/root.component.html b/src/app/components/root/root.component.html index 78627c2..1ab0348 100644 --- a/src/app/components/root/root.component.html +++ b/src/app/components/root/root.component.html @@ -18,9 +18,9 @@
- - - + + +
@@ -31,7 +31,7 @@
- {{pageType$ | async}} + {{pageType}}
diff --git a/src/app/components/root/root.component.ts b/src/app/components/root/root.component.ts index a00456f..69cf062 100644 --- a/src/app/components/root/root.component.ts +++ b/src/app/components/root/root.component.ts @@ -1,5 +1,5 @@ import {Component, OnInit} from '@angular/core'; -import {ActivatedRoute, Router} from '@angular/router'; +import {ActivatedRoute, NavigationEnd, ParamMap, Router} from '@angular/router'; import {StateService} from '../../services/state.service'; import {Observable} from 'rxjs/Observable'; @@ -14,37 +14,67 @@ export class RootComponent implements OnInit { title = 'Joachim Homepage'; mousingOver: string = null; - pageType$: Observable; + pageType: string; constructor(private router: Router, private route: ActivatedRoute, private stateService: StateService) { } ngOnInit() { - console.log('oninit of root component'); + // console.log('oninit of root component'); this.route.paramMap.subscribe(val => console.log(val)); - this.stateService.getLanguageFromRoute(this.route).subscribe(val => {console.log('ngoninit root language: ' + val)}); + // this.stateService.getLanguageFromRoute(this.route).subscribe(val => { + // console.log('ngoninit root language: ' + val) + // }); - this.pageType$ = this.stateService.getLanguageFromRoute(this.route).map(language => { - if (this.router.url.endsWith('posts')) { - return 'Posts'; + /** + * Listen to changes in the param map (this is the root level, so will only see changes in 'language'. good! + */ + this.route.paramMap.subscribe((paramMap: ParamMap) => { + const language = paramMap.get('language'); + console.log(`root comp listens for parammap: ${language}`) + // console.log('root: parammap changed ' + language); + if (language !== null) { + console.log('the subscriber of root changes the language to '+language); + this.stateService.setLanguage(language, this.route, this.router); } - if (this.router.url.endsWith('cv')) { - return 'Curriculum Vitae'; - } - if (this.router.url.endsWith('home')) { - if (language === 'nl') { - return 'Intro'; - } else { - return 'Home'; - } - } - return 'Joa did something wrong...' }); + + // we listen to a 'navigation end' event -> at that point we need update our pagetype string + this.router.events.filter(event => event instanceof NavigationEnd).subscribe(event => { + // navigated somewhere, got to make sure the pagetype has updated too + this.updatePageType(); + }); + + // do the first update for the page type + this.updatePageType(); + + + } + + /** + * Update the pagetype according to the right language and current router url. + */ + updatePageType() { + // console.log('firing update page type'); + // console.log(this.router.url); + if (this.router.url.endsWith('posts')) { + this.pageType = 'Posts'; + } else if (this.router.url.endsWith('cv')) { + this.pageType = 'Curriculum Vitae'; + } else if (this.router.url.endsWith('home')) { + if (this.stateService.getLanguage() === 'nl') { + this.pageType = 'Thuis'; + } else { + this.pageType = 'Home'; + } + } else { + this.pageType = 'Joa did something wrong...'; + } } mouseOver(s: string) { - console.log('mouseover!' + s); + // console.log('mouseover!' + s); this.mousingOver = s; } @@ -53,14 +83,15 @@ export class RootComponent implements OnInit { } toggleLanguage() { - this.stateService.getLanguageFromRoute(this.route).first().subscribe(val => { - if (val === 'nl') { - this.stateService.setLanguage('en', this.route, this.router); - } else if (val === 'en') { - this.stateService.setLanguage('nl', this.route, this.router); - } else { - console.log('Could not toggle the language, pirates stole your tongue.'); - } - }); + console.log('toggleLanguage called'); + if (this.stateService.getLanguage() === 'nl') { + console.log(' > toggle switched to en'); + this.stateService.setLanguage('en', this.route, this.router); + } else if (this.stateService.getLanguage() === 'en') { + this.stateService.setLanguage('nl', this.route, this.router); + console.log(' > toggle switched to nl'); + } else { + console.log(' > Could not toggle the language, pirates stole your tongue.'); + } } } diff --git a/src/app/model/post.ts b/src/app/model/post.ts index b0be284..65068a8 100644 --- a/src/app/model/post.ts +++ b/src/app/model/post.ts @@ -1,12 +1,13 @@ export class Post { type: string; + languages: string[]; title: any; - id:String; + id: String; created_timestamp: Date; tags: string[]; - constructor(id:String) { + constructor(id: String) { this.id = id; } } diff --git a/src/app/services/dataloader.service.ts b/src/app/services/dataloader.service.ts index 3c835b9..6c0b703 100644 --- a/src/app/services/dataloader.service.ts +++ b/src/app/services/dataloader.service.ts @@ -5,6 +5,7 @@ import { Observable } from 'rxjs/Observable'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import 'rxjs/add/operator/map'; +import 'rxjs/add/observable/of'; @Injectable() export class DataloaderService { @@ -17,11 +18,12 @@ export class DataloaderService { // fill it up for (const index in posts) { const post: any = posts[index]; - console.log(post); + // console.log(post); const temp: Post = new Post(post.id); temp.title = post.info.title; temp.type = post.type; temp.tags = post.info.tags; + temp.languages = post.info.languages; // console.log('got this timestamp: ' + post.info.created_timestamp); temp.created_timestamp = new Date(post.info.created_timestamp * 1000); // console.log('converted it to this: ' + temp.created_timestamp); @@ -37,18 +39,24 @@ export class DataloaderService { * Fetch the 'full fat' post. This returns HTML content that can be wrapped in any container, no sanitizing done. * @param filename the filename for which the post needs to be fetched */ - getPost(id: String): Observable { + getFullHtml(post: Post, language: string): Observable { const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'text/html', 'Accept': 'text/html' }) }; - // console.log('launching GET'); - const url = 'assets/post/' + id + '/full.html'; + // check if the post actually has a filename for the 'full version' and the post is translated to the given language + if (post.languages === undefined) { + console.log(`post with id ${post.id} has no languages defined...`); + return Observable.of('You encounter a pirate without a tongue. Curious.'); + } + if (post.languages.indexOf(language) !== 1) { + // language is defined! + const url = `assets/post/${post.id}/full-${language}.html`; + return this.http.get(url, {responseType: 'text'}); + } else { + return Observable.of('You encounter a pirate without a tongue. Curious.'); + } - // console.log('fetching: '+url); - // console.log('getPost called: '+url); - - return this.http.get(url, {responseType: 'text'}); } } diff --git a/src/app/services/state.service.ts b/src/app/services/state.service.ts index 02d823e..b18b8e8 100644 --- a/src/app/services/state.service.ts +++ b/src/app/services/state.service.ts @@ -2,29 +2,29 @@ import {Injectable, OnInit} from '@angular/core'; import {Post} from '../model/post'; import {ActivatedRoute, ParamMap, Router} from '@angular/router'; import 'rxjs/add/operator/filter'; -import {Observable} from 'rxjs/Observable'; @Injectable() export class StateService { // this keeps track of which type is enabled / disabled - tagFilter: any = []; + private tagFilter: any = []; + private language: string; constructor() { } - /** - * Get the language currently set in the router. - * - * @param {ActivatedRoute} route - * @returns {Observable} - */ - getLanguageFromRoute(route: ActivatedRoute): Observable { - return route.paramMap.map((params: ParamMap) => { - const temp = params.get('language'); - return temp; - }); - } + // /** + // * Get the language currently set in the router. + // * + // * @param {ActivatedRoute} route + // * @returns {Observable} + // */ + // getLanguageFromRoute(route: ActivatedRoute): Observable { + // return route.paramMap.map((params: ParamMap) => { + // const temp = params.get('language'); + // return temp; + // }); + // } shouldDisplay(post: Post): boolean { // check whether all filters are true or false: that case, just show everything @@ -48,10 +48,10 @@ export class StateService { return true; } - //check whether the post should be displayed + // check whether the post should be displayed for (const tag of Object.keys(this.tagFilter)) { if (post.tags.indexOf(tag) != -1 && this.tagFilter[tag] === true) { - //found the tag and its filter is enabled + // found the tag and its filter is enabled return true; } } @@ -75,23 +75,22 @@ export class StateService { } } - setLanguage(language: string, route: ActivatedRoute, router: Router) { - console.log('setting language: '+language); - // // check out the current route - // route.pathFromRoot.forEach(path=>{ - // console.log(path); - // console.log(path.routeConfig); - // }); - router.navigate([language]); + /** + * Get the currently set language. + * @returns {string} + */ + getLanguage() { + return this.language; + } - // route.url.subscribe(segments => { - // console.log(segments); - // //now also do the children - // route.children.forEach(child => { - // child.url.subscribe(childsegment => { - // console.log(childsegment); - // }); - // }); - // }); + setLanguage(language: string, route: ActivatedRoute, router: Router) { + console.log(`want to switch to: ${language} from ${this.language}`) + if (this.language !== language) { + console.log('setting language (triggers navigate): ' + language); + this.language = language; + router.navigate([language]); + } else { + console.log('setting language did nothing: no navigation.') + } } } diff --git a/src/assets/post/cupboard1/full.html b/src/assets/post/cupboard1/full-en.html similarity index 100% rename from src/assets/post/cupboard1/full.html rename to src/assets/post/cupboard1/full-en.html diff --git a/src/assets/post/cupboard1/full-nl.html b/src/assets/post/cupboard1/full-nl.html new file mode 100644 index 0000000..0aca267 --- /dev/null +++ b/src/assets/post/cupboard1/full-nl.html @@ -0,0 +1 @@ +

Dit gaat over de eerste kast.

diff --git a/src/assets/post/cupboard1/info.json b/src/assets/post/cupboard1/info.json index 7fb187c..e12c701 100644 --- a/src/assets/post/cupboard1/info.json +++ b/src/assets/post/cupboard1/info.json @@ -1 +1,14 @@ -{"created_timestamp": 1515094644.215065, "title": "cupboard", "tags":["project"]} +{ + "created_timestamp": 1515094644.215065, + "title": { + "en": "Cupboard", + "nl": "De kast" + }, + "tags": [ + "project" + ], + "languages": [ + "nl", + "en" + ] +} diff --git a/src/assets/post/first/full.html b/src/assets/post/first/full-en.html similarity index 75% rename from src/assets/post/first/full.html rename to src/assets/post/first/full-en.html index f5ca78d..9ad2508 100644 --- a/src/assets/post/first/full.html +++ b/src/assets/post/first/full-en.html @@ -1,8 +1,11 @@ -

It's been on my mind for a while now to create an oldschool homepage. So, here it is. An homage to the old and tried +

It's been on my mind for a while now to create an oldschool homepage. So, here it is. An homage to the old and + tried Web 1.0, whoever thought static web pages were done and dusted is wrong! This will be a collection of some - technical things I want to remind myself about so I don't have to look them up again and again, miscellaneous pictures + technical things I want to remind myself about so I don't have to look them up again and again, miscellaneous + pictures of projects (in-progress or done) or anything that comes to mind I'd like to share on something other than the usual social media suspects.

-

Besides, it's nice to have a minimalistic Angular2/Bootstrap playground to do some styling experiments. I'll probably update +

Besides, it's nice to have a minimalistic Angular2/Bootstrap playground to do some styling experiments. I'll + probably update this thing once in a while. Maybe even use a database, wouldn't that be something...

diff --git a/src/assets/post/first/full-nl.html b/src/assets/post/first/full-nl.html new file mode 100644 index 0000000..60c515a --- /dev/null +++ b/src/assets/post/first/full-nl.html @@ -0,0 +1 @@ +

Dit moet ik vertalen, de eerste post!

diff --git a/src/assets/post/first/info.json b/src/assets/post/first/info.json index 431a308..0401f43 100644 --- a/src/assets/post/first/info.json +++ b/src/assets/post/first/info.json @@ -1 +1,11 @@ -{"created_timestamp": 1515094679.342938, "title": "Who said Web 1.0 was dead anyway?", "tags":["blog"]} +{ + "created_timestamp": 1515094679.342938, + "title": { + "en": "Who said Web 1.0 was dead anyway?", + "nl": "Web 1.0 is niet dood joh!" + }, + "tags": [ + "blog" + ], + "languages": ["nl", "en"] +} diff --git a/src/assets/post/lxdarch/full.html b/src/assets/post/lxdarch/full-en.html similarity index 100% rename from src/assets/post/lxdarch/full.html rename to src/assets/post/lxdarch/full-en.html diff --git a/src/assets/post/lxdarch/full-nl.html b/src/assets/post/lxdarch/full-nl.html new file mode 100644 index 0000000..22cc8ff --- /dev/null +++ b/src/assets/post/lxdarch/full-nl.html @@ -0,0 +1 @@ +

LXD is pretty cool kerels.

diff --git a/src/assets/post/lxdarch/info.json b/src/assets/post/lxdarch/info.json index e01ecb7..f293432 100644 --- a/src/assets/post/lxdarch/info.json +++ b/src/assets/post/lxdarch/info.json @@ -1 +1,11 @@ -{"created_timestamp": 1515094644.215333, "title": "some things about lxc in arch", "tags":["tech"]} +{ + "created_timestamp": 1515094644.215333, + "title": { + "en": "Some things about LXD", + "nl": "LXD is cool!" + }, + "tags": [ + "tech" + ], + "languages": ["en", "nl"] +} diff --git a/src/assets/post/test/full.html b/src/assets/post/test/full-en.html similarity index 100% rename from src/assets/post/test/full.html rename to src/assets/post/test/full-en.html diff --git a/src/assets/post/test/full-nl.html b/src/assets/post/test/full-nl.html new file mode 100644 index 0000000..0f3b94b --- /dev/null +++ b/src/assets/post/test/full-nl.html @@ -0,0 +1 @@ +

Dit is een test post.

diff --git a/src/assets/post/test/info.json b/src/assets/post/test/info.json index 2c83320..ba32389 100644 --- a/src/assets/post/test/info.json +++ b/src/assets/post/test/info.json @@ -1,5 +1,15 @@ { - "created_timestamp": 1515095948.838848, - "title": "Test title", - "tags":["tech", "blog"] + "created_timestamp": 1515095948.838848, + "title": { + "en": "Test title", + "nl": "Test titel!" + }, + "tags": [ + "tech", + "blog" + ], + "languages": [ + "nl", + "en" + ] } diff --git a/src/assets/posts.json b/src/assets/posts.json index 091bb40..9816a8b 100644 --- a/src/assets/posts.json +++ b/src/assets/posts.json @@ -1 +1 @@ -[{"info": {"created_timestamp": 1515094679.342938, "tags": ["blog"], "title": "Who said Web 1.0 was dead anyway?"}, "id": "first"}, {"info": {"created_timestamp": 1515094644.215065, "tags": ["project"], "title": "cupboard"}, "id": "cupboard1"}, {"info": {"created_timestamp": 1515095948.838848, "tags": ["tech", "blog"], "title": "Test title"}, "id": "test"}, {"info": {"created_timestamp": 1515094644.215333, "tags": ["tech"], "title": "some things about lxc in arch"}, "id": "lxdarch"}] \ No newline at end of file +[{"id": "cupboard1", "info": {"created_timestamp": 1515094644.215065, "title": {"en": "Cupboard", "nl": "De kast"}, "tags": ["project"], "languages": ["nl", "en"]}}, {"id": "first", "info": {"created_timestamp": 1515094679.342938, "title": {"en": "Who said Web 1.0 was dead anyway?", "nl": "Web 1.0 is niet dood joh!"}, "tags": ["blog"], "languages": ["nl", "en"]}}, {"id": "lxdarch", "info": {"created_timestamp": 1515094644.215333, "title": {"en": "Some things about LXD", "nl": "LXD is cool!"}, "tags": ["tech"], "languages": ["en", "nl"]}}, {"id": "test", "info": {"created_timestamp": 1515095948.838848, "title": {"en": "Test title", "nl": "Test titel!"}, "tags": ["tech", "blog"], "languages": ["nl", "en"]}}] \ No newline at end of file diff --git a/src/scripts/compileposts.py b/src/scripts/compileposts.py index 3046065..76c77b5 100644 --- a/src/scripts/compileposts.py +++ b/src/scripts/compileposts.py @@ -25,7 +25,7 @@ for post in posts: temp['info'] = d; # have to write the 'modified date' in the info.json of the post if it's not there yet - if not d.has_key('created_timestamp'): + if 'created_timestamp' not in d: d['created_timestamp'] = time.time() # persist it in the json file itself with open(infofile, 'w') as infooutfile: