Skip to content

Commit

Permalink
Fixed a bug with the sort order button, made infinite scrolling smoot…
Browse files Browse the repository at this point in the history
…her, fixed other stuff
  • Loading branch information
dkvz committed Jan 21, 2018
1 parent 934def2 commit b22c96f
Show file tree
Hide file tree
Showing 17 changed files with 162 additions and 83 deletions.
95 changes: 73 additions & 22 deletions README.md
@@ -1,28 +1,71 @@
NOTHING HERE YET
# JS Blog Engine
This project is an experiment producing a blog engine similar to one I made using Polymer 1.0 but with no frameworks.

# DONT READ THIS
This readme is currently mostly a todo list an a project notepad. I'll write the sections on how to run the site later.
I do use Webpack, the Javascript router Page.js and the MaterializeCSS project. The site could live without Webpack although it would take some work to put everything together manually. One of my requirements was that this had to survive a hypothetical global apocalypse in which someone issues a `rm -rf node_modules` that affects all the computers in the world, until the end of times.

I'm a weird person.

The site populates its dynamic content using calls to this other project: [dorade-blog-engine](https://github.com/dkvz/dorade-blog-engine) which was whipped up very quickly so please don't look at the code there.

## Pre-requisites
* NodeJS version 6+

## Install
Clone the repository. Get inside the project directory and run:
```
npm install
```

## Testing the website
To run the test server on Windows and OSX (port 8080):
```
npm run dev
```

For Windows use:
```
npm run dev-win
```
The Windows command probably also works on Linux and OSX. I haven't actually tested.

## Building for prod
To minify (almost) everything for production use:
```
npm run prod
```
Which will remove then create the 'dist' folder.

To serve the website on Apache, Nginx or others you'll need to use a fallback resource to index.html or a rewrite that has the same effect.

## Supported browsers
We use addEventListener and removeEventListener, I added a polyfill just for kicks.
The polyfill for addEventListener and removeEventListener is acutally useless since Materialize is not supposed to be supported below IE 11 and I also use classList at some point.

The pinned toolbar on scrolling might also not work on IE 8, same with the infinite scrolling (which might even not work on IE 9).

We're not providing a polyfill for the routing, which uses HTML 5 pushstate API. I think only IE 10 supports it but I might be wrong on that.

Materialize is not supposed to be supported below IE 11.
I need to write Modernizr code and create a page for non-supported browsers.

## The anchor link issue
## DONT READ THIS
This readme is currently mostly a todo list an a project notepad. I'll write the sections on how to run the site later.

There is a gigantic TODO section at the bottom that can be seen as some sort of ugly roadmap (to hell).

### The anchor link issue
When I use an anchor link to #something on my article pages it reloads the article.
However, using the anchor link in the browser address bar works.

I have a few leads.

### Using location.hash in script
#### Using location.hash in script
It doesn't work for my toBottom code at the moment though.

I'm going to try in dev console => It works but not the first time we do it:
```
window.location.hash = 'toc_1_4'
```

### Do something at the router level
#### Do something at the router level
I think page.js is interfering with the hash link.
What is weird is that clicking a hash link first reload the article, but clicking it a second time after that works.

Expand All @@ -34,7 +77,7 @@ The router data passed to the callback has a "hash" property. I think we need to

### Old stuff

## Previous spinner injection
#### Previous spinner injection
```
// Add the spinner thingy to indicate loading:
app.spinner = app.createElementFromText(
Expand All @@ -50,7 +93,7 @@ app.hideSpinner = function() {
```
I just removed the createElement thingy and replaced it with a getElementById.

## Optimize CSS
### Optimize CSS
I think I should use this:
```
// Compress extracted CSS. We are using this plugin so that possible
Expand All @@ -63,7 +106,7 @@ I think I should use this:
```
Detecting duplicate CSS seems interesting.

## The FOUC issue
### The FOUC issue
I think I need the extract text plugin to solve the FOUC issue. HtmlWebpackPlugin is supposed to add the CSS to head automatically if using extract text plugin.

Let's see how I can make this work... I'll test some of this stuff in my test project.
Expand Down Expand Up @@ -93,21 +136,21 @@ And declare the plugin in your plugins section.

Then that's it, FOUC issue solved.

## TODO
### TODO

* What is the CSS style text-size-adjust?
* There is no table style or it's wrong in my articles.
* In beves and articleCard I had to remove the quotes around "layout" and add them in the JS code because otherwise uglify would remove the quotes from the template. I don't know if that's a bug with Uglify or if I'm missing something.

* In breves and articleCard I had to remove the quotes around "layout" and add them in the JS code because otherwise uglify would remove the quotes from the template. I don't know if that's a bug with Uglify or if I'm missing something.
* When loading article cards the console is saying Roboto from the materialize website has been blocked because it's not using HTTPS. Why is it trying to download Roboto from there? What does this even mean?
* Try to add the thing that compresses images with webpack. Low priority.
* Isn't there something better than using margin-left and margin-right to make my float elements no stick too close to the text?
* To gototop button should be on the main template. Just show it when required.
* Add the unsupported browsers thingy.
* I NEED THE MANIFEST PLUGIN and use that to load my fragments with their right hashes.
* Try the new image code on the old blog in a hidden article.
* All the initialization stuff might have to be put in a "document ready" bloc. Not sure.
* I need to test the infinite scrolling on a huge resolution.
* The mobile menu has weird bottom margin issues.
* Not really on Chrome.
* Pagejs requires html5 history api, I think it doesn't work on IE 8 (to check) - There is a polyfill.
* What is the CSS style text-size-adjust?
* List style is better but maybe could be better in articles.
* Test on mobile and tablets, the infinite scrolling might not work on there.
* Use the SASS CSS from materialize. If I do that, I need to replace mentions to Roboto in my css file and replace that with the SASS variable used for the base font family.
Expand All @@ -121,13 +164,21 @@ Then that's it, FOUC issue solved.
* When the backend returns a 404 the jquery AJAX stuff always outputs a parse error as well. I might have to still return content type json on my errors, or add a listener to ajax errors and prevent the output.
* We could delcare a contructor for the app object and call new somehwere. I think react works like that.
* Check how cookie clicker does it. I like it because the code of cookie clicker is super dirty.
* Technically if we're already on the articles page, we don't have to reload it entirely if we click a tag, we just need to refresh the loaded articles.
* We could just cache the generated root elements of pages, since we don't need to re-fetch that stuff. We'd have to be careful of event listeners sticking around with these elements. I have to check the performances on mobile, but it could be a good idea.
* We would just be keeping the document fragment.
* I'm probably going to have to do this for performances reasons.
* Theme color in the manifest.json is wrong.
* The styles folder should be inside src. I mean that is arguable.
* Add "exit page" callbacks in routing to unregister event listeners on some pages.
* Removing nodes also GCs the listeners, but not very effectively on old IE versions (as in IE 8).
* So this is very low priority.
* npm run dev doesn't work on windows. I made another command: npm run dev-win. But that is more like a hack. I'm also not 100% sure it even works. Or if it doesn't set the env to dev forever after it ran once.
* npm run dev doesn't work on windows. I made another command: npm run dev-win. But that is more like a hack. I'm also not 100% sure it even works. Or if it doesn't set the env to dev forever after it ran once.

### Historical
* Scrolling to comments doesn't work anymore. It kinda does but then I think the repaint due to some images is causing the scroll position to be wrong.
* I've put a setTimeout of 1s before scrolling. Won't be enough for slow connections.
* There is no table style or it's wrong in my articles.
* I have to use thead, and the class responsive-table is nice.
* Technically if we're already on the articles page, we don't have to reload it entirely if we click a tag, we just need to refresh the loaded articles.
* We could just cache the generated root elements of pages, since we don't need to re-fetch that stuff. We'd have to be careful of event listeners sticking around with these elements. I have to check the performances on mobile, but it could be a good idea.
* We would just be keeping the document fragment.
* I'm probably going to have to do this for performances reasons.
* All the initialization stuff might have to be put in a "document ready" bloc. Not sure.
* I don't need it because my JS is at the end of body. This stackoverflow question has some nice replacements for document ready though: https://stackoverflow.com/questions/799981/document-ready-equivalent-without-jquery
Binary file added assets/Thumbs.db
Binary file not shown.
Binary file added assets/shorts/Thumbs.db
Binary file not shown.
Binary file added assets/shorts/shorts_art1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/shorts/shorts_art1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/shorts/shorts_art2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/shorts/shorts_computers1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/shorts/shorts_computers1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/shorts/shorts_cooking2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/shorts/shorts_gaming1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/shorts/shorts_philo1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/shorts/shorts_windows3.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/touch/Thumbs.db
Binary file not shown.
137 changes: 77 additions & 60 deletions src/app.js
Expand Up @@ -239,14 +239,24 @@ var app = {
return this.quotes[Math.floor(Math.random() * this.quotes.length)];
},
setActiveMenuTag: function(tagName) {
for (var i = 0; i < this.tags.length; i++) {
if (this.tags[i].name === tagName || this.tags[i].nameEncoded === tagName) {
document.getElementById('menuTagL' + this.tags[i].id).className = 'active';
document.getElementById('menuTagM' + this.tags[i].id).className = 'active';
} else {
// Stuff here could be refactored.
if (!tagName) {
document.getElementById('menuTagAll').className = 'active';
for (var i = 0; i < this.tags.length; i++) {
document.getElementById('menuTagL' + this.tags[i].id).className = '';
document.getElementById('menuTagM' + this.tags[i].id).className = '';
}
} else {
for (var i = 0; i < this.tags.length; i++) {
document.getElementById('menuTagAll').className = '';
if (this.tags[i].name === tagName || this.tags[i].nameEncoded === tagName) {
document.getElementById('menuTagL' + this.tags[i].id).className = 'active';
document.getElementById('menuTagM' + this.tags[i].id).className = 'active';
} else {
document.getElementById('menuTagL' + this.tags[i].id).className = '';
document.getElementById('menuTagM' + this.tags[i].id).className = '';
}
}
}
},
setMenuItemActive: function(menuId) {
Expand Down Expand Up @@ -543,76 +553,83 @@ var app = {
app.hideSpinner();
});
},
resetBottomReached: function() {
setTimeout(function() {
app.bottomReached = false;
}, 300);
},
loadMoreContentOnpage: function(page) {
if (!app.bottomReached) {
console.log('Loading more data...');
app.bottomReached = true;
switch(page) {
case 'articles':
app.showSpinner();
app.loadArticlesOrShorts(
app.loadedCount,
app.maxArticles,
false,
app.orderDesc ? 'desc' : 'asc',
'articles',
app.homeLayoutA,
function() {
app.hideSpinner();
app.bottomReached = false;
}
);
break;
case 'article':
console.log('Loading comments...');
app.showSpinner();
app.loadComments(
app.loadedCount,
app.maxComments,
function() {
app.hideSpinner();
app.bottomReached = false;
}
);
break;
case 'breves':
console.log('Loading more shorts...');
app.showSpinner();
app.loadArticlesOrShorts(
app.loadedCount,
app.maxShorts,
true,
app.orderDesc ? 'desc' : 'asc',
'articles',
app.layoutS,
function() {
app.hideSpinner();
app.bottomReached = false;
}
);
break;
default:
// Remove the listener, we're not on a
// supported page.
app.disableInfiniteScrolling();
}
console.log('Loading more data...');
app.bottomReached = true;
switch(page) {
case 'articles':
app.showSpinner();
app.loadArticlesOrShorts(
app.loadedCount,
app.maxArticles,
false,
app.orderDesc ? 'desc' : 'asc',
'articles',
app.homeLayoutA,
function() {
app.hideSpinner();
app.resetBottomReached();
}
);
break;
case 'article':
console.log('Loading comments...');
app.showSpinner();
app.loadComments(
app.loadedCount,
app.maxComments,
function() {
app.hideSpinner();
app.resetBottomReached();
}
);
break;
case 'breves':
console.log('Loading more shorts...');
app.showSpinner();
app.loadArticlesOrShorts(
app.loadedCount,
app.maxShorts,
true,
app.orderDesc ? 'desc' : 'asc',
'articles',
app.layoutS,
function() {
app.hideSpinner();
app.resetBottomReached();
}
);
break;
default:
// Remove the listener, we're not on a
// supported page.
app.disableInfiniteScrolling();
}
},
inifinteScrollCallback: function() {
// I could use window.innerHeight without jQuery but
// it's IE 9+ only.
var inner = $('#mainEl').innerHeight();
var thres;
if ($(document).width() >= 1300) {
if ($(document).width() > 2000) {
thres = 900;
} else if ($(document).width() >= 1300) {
thres = 580;
} else {
thres = 265;
}
var curDiff = window.pageYOffset - inner;
if (Math.abs(curDiff) < thres &&
Math.abs(curDiff) >= app.previousDiff) {
app.previousDiff = Math.abs(curDiff) - 20;
app.loadMoreContentOnpage(app.currentPage);
if (!app.bottomReached) {
app.previousDiff = Math.abs(curDiff) - 20;
app.loadMoreContentOnpage(app.currentPage);
}
}
/* var inner = window.innerHeight;
var curDiff = window.pageYOffset - inner;
Expand Down
8 changes: 7 additions & 1 deletion src/article.js
Expand Up @@ -186,7 +186,13 @@ app.loadArticle = function(articleId, hash, toc) {
if (hash && hash !== '') {
//location.hash = '';
//location.hash = hash;
location.href = '#' + hash;
// My images don't have height, so they cause
// a big reflow when loading which makes going
// to a specific anchor too fast unreliable.
// Hence the 1 second timeout here:
setTimeout(function() {
location.href = '#' + hash;
}, 1000);
}
app.fragments.article.initPage();
app.bottomReached = false;
Expand Down
1 change: 1 addition & 0 deletions src/articles.js
Expand Up @@ -19,6 +19,7 @@ app.fragments.articles.initPage = function() {
while (artEl.firstChild) {
artEl.removeChild(artEl.firstChild);
}
app.loadedCount = 0;
if (app.currentPage === 'articles') {
app.loadArticlesOrShorts(
0,
Expand Down
4 changes: 4 additions & 0 deletions src/routing.js
Expand Up @@ -92,6 +92,8 @@ page('/tag/:name', function(data) {
page('/breves', function() {
app.currentTags = [];
app.currentPage = 'breves';
app.setMenuItemActive('shortsL');
app.setActiveMenuTag();
app.showArticlesPage();
// The showArticlesPage function sets the active menu.
});
Expand All @@ -114,6 +116,8 @@ page('/articles', function() {
// Reset tags:
app.currentTags = [];
app.currentPage = 'articles';
app.setMenuItemActive('articlesL');
app.setActiveMenuTag();
app.showArticlesPage();
});
page('/articles/:name/:toBottom?', function(data) {
Expand Down

0 comments on commit b22c96f

Please sign in to comment.