<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><link type="application/atom+xml" href="/feed.xml" rel="alternate" title="Grumpy Website"/><link href="/static/favicons/apple-touch-icon-152x152.png" rel="apple-touch-icon-precomposed" sizes="152x152"/><link href="/static/favicons/favicon-196x196.png" rel="icon" sizes="196x196"/><link href="/static/favicons/favicon-32x32.png" rel="icon" sizes="32x32"/><title>Grumpy Website</title><style type="text/css">* { box-sizing: border-box; }

body {
font-family: sans-serif;
line-height: 140%;
padding: 0.25em 1em;
max-width: 652px; /* .post_img =>> 550px */
margin: 0 auto;
transition: 500ms ease-in-out;
}

.icon_rotate { width: 20px; height: 20px; display: inline-block; background: url("/static/rotate.svg"); margin: 5px 5px -5px -25px; }
@media (max-width: 679px) {
.icon_rotate { display: none; }
}

/* HEADER */

header { margin-bottom: 2em; }

.title { margin-bottom: 0; }
.title_back { position: absolute; margin-left: -1em; text-decoration: none; }
.title_back:hover { text-decoration: underline; }

.title_new { padding: 10px; margin: -10px 0 0 0; float: right; text-decoration: none; color: #c3c; }
.title_new:hover { color: #d4d; }
body.anonymous .title_new { display: none; }

.subtitle { margin-left: 0.09em;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none; }
.subtitle > span { cursor: pointer; }

/* POST */

.post { display: flex; justify-content: flex-start; margin-bottom: 2em; }
.post_side { margin-right: 20px; min-width: 50px; }
@media (max-width: 399px) {
.post_side { display: none; }
}
.post_avatar { width: 50px; height: 50px; }

.post_video_outer { position: relative; }
.post_video_overlay { position: absolute; top: 0; bottom: 0; left: 0; right: 0; cursor: pointer; }
.post_video_overlay-paused { background-color: rgba(0,0,0,0.3); background-image: url("/static/play.svg"); background-size: contain; background-position: center center; background-repeat: no-repeat; }
.post_video_overlay-paused:hover { background-color: rgba(0,0,0,0.25); }
.post_img, .post_video { display: block; margin-bottom: 1em; }
.post_img-fix { display: block; background-size: 100%; position: relative; }
.post_img-fix > img { position: absolute; height: 100%; }
.post_video,
.post_img-flex > img { display: block; max-width: 100%; height: auto; max-height: 500px; }
.post_author { font-weight: bold; }
.post_content { width: 100%; }
.post_body > p { margin: 0 0 1em 0; }

.post_meta_edit { float: right; color: #c3c; }
.post_meta_edit:hover { color: #d4d; }
body.anonymous .post_meta_edit { display: none; }

/* FOOTER */
@keyframes rotating {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}

.loader { margin: 0 0 3em 0; text-align: center; }
.loader > img { width: 76px; height: 76px; border: 2px solid #000; border-radius: 50%; }
.loader-loading > img { animation: rotating 1s ease-in-out infinite; }
.loader-error > img { cursor: pointer; border-color: red; }
.loader-error > img:hover { position: relative; top: -1px; }

footer {
padding: 1em 0 1em;
margin-top: 2em;
border-top: 1px solid #000;
}
</style><script>var subtitles =
[ 'Do you want to cancel? – YES / CANCEL',
'Select purchase to purchase for $0.00 – PURCHASE / CANCEL',
'This isn not text, this is a link. No not press.',
'Do not refresh this page, do not click Back',
'Error occured — OK',
'Password must be 8 characters including 1 uppercase letter and 1 number',
'Are you sure you want to exist? — YES / NO',
'Open in app',
'Warning: No pixels were selected',
'You need to be logged in to log out. Please log in to log out.',
// 'Cancel changes? – CANCEL / CHANGE',
'Cancel subscription? – YES / CANCEL',
'Please, try again later',
'You need to login to unsubscribe',
'Update Java Runtime?',
'Your PC will automatically restart in one minute',
'grumpy.website wants to: Show notifications',
'You are using an outdated browser',
'How likely are you to recommend grumpy.website to your friends?',
'The system has recovered from a serious error',
'Are you in Boston? — YES / SELECT ANOTHER',
'Hi Carol, thanks for signing up! My name is Kevin...',
'We use cookies on this website to make your browsing experience better',
'By using the site you agree to our use of cookies',
'[ ] Don\'t show this again',
'This page requires you to use a recent browser (Internet Explorer 5+ or Netscape Navigator 7.0)',
'Like failed',
'Add to Home Screen',
'In high demand—6 other people are looking at this page',
'You’ve read 9 stories this month. Let’s make things official',
'Medium follows Do Not Track but we track to personalize your experience and send data to select third-parties to make our features work',
'Plugin is ready to update',
'Part 2 of 3: Installing features and drivers. 50% complete',
'Don’t turn off your computer, this will take a while',
'Данный ресурс заблокирован! по решению Роскомнадзора',
'Already a member? Sign in.',
'Trust this computer?',
'Why am I seeing this?',
'Drop images here to send them in a quick way',
'Choose an account to continue',
'The operation can’t be completed because it isn’t supported',
'Are you sure you want to close all programs and shut down the computer?',
'Please take a moment to rate your experience',
'Would you like to save this file?',
',   ?',
'This app is using significant energy',
'The disk was not ejected properly',
'Trying to regain internet connection... Hide this message.',
'Loading...',
'Remind me tomorrow',
'Stop showing me this',
'Why am I seeing this?',
'See fewer posts like this',
'This content is not available in your country',
'This website wants to know your location',
'We’re sorry! You need to update your Flash Player.',
'You have one unread message',
'We are updating our privacy policy'],
subtitle_el,
subtitle_idx = subtitles.length;

function shuffle(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}

function reload_subtitle() {
++subtitle_idx;
if (subtitle_idx >= subtitles.length) {
shuffle(subtitles);
subtitle_idx = 0;
}
subtitle_el.innerHTML = subtitles[subtitle_idx];
}

window.addEventListener("DOMContentLoaded", function() {
subtitle_el = document.querySelector('.subtitle-text');
subtitle_el.onclick = reload_subtitle;
reload_subtitle();
if (document.cookie.indexOf("grumpy_user=") >= 0) {
document.body.classList.remove("anonymous");
}
});

var rotate_angle_deg = 0;

function body_rotate() {
rotate_angle_deg += 180;
document.body.style.transform = "rotate(" + rotate_angle_deg + "deg)";
}

function toggle_video(wrapper, play) {
var video = wrapper.querySelector("video"),
overlay = wrapper.querySelector(".post_video_overlay");
if (play) {
overlay.classList.remove("post_video_overlay-paused");
} else if (video.paused) {
video.play();
overlay.classList.remove("post_video_overlay-paused");
} else {
video.pause();
overlay.classList.add("post_video_overlay-paused");
}
}
</script><script>var loader_status = "IDLE",
loader;

function load_posts() {
loader_status = "LOADING";
loader.classList.add("loader-loading");
loader.classList.remove("loader-error");
loader.querySelector("img").removeEventListener("click", load_posts);
var posts = document.querySelectorAll(".post"),
last_post = posts[posts.length - 1],
last_post_id = last_post.getAttribute("data-id");

var req = new XMLHttpRequest();

req.addEventListener("load", function() {
loader.classList.remove("loader-loading");
var resp = this;
if (resp.status !== 200) {
loader_status = "ERROR";
loader.classList.add("loader-error");
loader.querySelector("img").addEventListener("click", load_posts);
} else if (resp.responseText.length === 0) {
loader_status = "DONE";
loader.remove();
} else {
var div = document.createElement("div");
div.innerHTML = resp.responseText;
loader.parentNode.insertBefore(div, loader);
loader_status = "IDLE";
}
});

req.open("GET", '/after/' + last_post_id);
req.send();
}

function on_scroll(e) {
var cont = document.body,
full_height = cont.scrollHeight,
viewport_height = window.innerHeight,
scrolled = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop,
scrolled_bottom = scrolled + viewport_height,
at_bottom = scrolled_bottom >= full_height - 200;

if ( at_bottom && loader_status === "IDLE" )
load_posts();
}

window.addEventListener("DOMContentLoaded", function() {
loader = document.querySelector(".loader");
on_scroll();
window.addEventListener("scroll", on_scroll);
});</script></head><body class="anonymous"><header><h1 class="title">Grumpy Website<a href="/new" class="title_new">+</a></h1><p class="subtitle"><span onclick="body_rotate()" class="icon_rotate"></span><span class="subtitle-text"> </span></p></header><div data-id="0T6kDVGD2" class="post"><div class="post_side"><img src="/static/nikitonsky.jpg" class="post_avatar"/></div><div class="post_content"><div style="max-width:231px"><a href="/post/0T6kDVGD2/LycvDQV.orig.jpeg" target="_blank" style="padding-bottom:216.4502164502165%" class="post_img post_img-fix"><img src="/post/0T6kDVGD2/LycvDQV.fit.jpeg"/></a></div><div class="post_body"><p><span class="post_author">nikitonsky: </span>Let’s think for a second how “Watch in fullscreen” button should work. When I click it, I clearly express an intent: I want to see this video in the most comfortable way possible, without any distractions. It might sound controversial, but normally it DOESN’T mean a tiny little rectangle in the center of my screen. GO HORIZONTAL! Yes I didn’t turn my phone (yet), but I already pressed a button to watch fullscreen! This tiny scaled down rectangle doesn’t work for anything, in any condition, anyway. Why show it at all?</p><p>Before you ask, yes, even if I locked my screen orientation to portrait before, I STILL want fullscreen videos (and only videos) to be shown in landscape. Because anything else makes sense.</p><p>P.S. controlling your phone orientation with actaully rotating your phone (you know, in a physical space) still sucks. I’ll take a button, even an on-screen button, over this any time.</p><p>Thx @s_sarkisian for the picture</p></div><p class="post_meta">January 15, 2020 // <a href="/post/0T6kDVGD2">Hyperlink</a><a href="/post/0T6kDVGD2/edit" class="post_meta_edit">Edit</a></p></div></div><div data-id="0T6R-hWaP" class="post"><div class="post_side"><img src="/static/nikitonsky.jpg" class="post_avatar"/></div><div class="post_content"><div style="max-width:550px"><a href="/post/0T6R-hWaP/LyZC3zQ.orig.png" target="_blank" style="padding-bottom:58.63636363636364%" class="post_img post_img-fix"><img src="/post/0T6R-hWaP/LyZC3zQ.fit.jpeg"/></a></div><div class="post_body"><p><span class="post_author">nikitonsky: </span>Sorry, I just don’t understand putting field name inside the text field. I mean, text field is a place where you are supposed to write YOUR answer. Form design should INVITE you to put your answers there. Empty space should be left empty to COMMUNICATE that YOU need to fill it in. Here everything is already filled, what do you need from me?</p></div><p class="post_meta">January 14, 2020 // <a href="/post/0T6R-hWaP">Hyperlink</a><a href="/post/0T6R-hWaP/edit" class="post_meta_edit">Edit</a></p></div></div><div data-id="0T64O7VKa" class="post"><div class="post_side"><img src="/static/nikitonsky.jpg" class="post_avatar"/></div><div class="post_content"><div style="max-width:457px"><a href="/post/0T64O7VKa/LyTfvAq.orig.png" target="_blank" style="padding-bottom:109.375%" class="post_img post_img-fix"><img src="/post/0T64O7VKa/LyTfvAq.fit.jpeg"/></a></div><div class="post_body"><p><span class="post_author">nikitonsky: </span>When there’s plenty of space for showing all details at once yet you still need to manually enable them. Bonus for classic “guess which of two tabs is selected” problem</p><p>Thx @akivag29 for the pictures</p></div><p class="post_meta">January 13, 2020 // <a href="/post/0T64O7VKa">Hyperlink</a><a href="/post/0T64O7VKa/edit" class="post_meta_edit">Edit</a></p></div></div><div data-id="0T5l0I4Gy" class="post"><div class="post_side"><img src="/static/nikitonsky.jpg" class="post_avatar"/></div><div class="post_content"><div class="post_video_outer"><video autoplay="" muted="" loop="" preload="auto" playsinline="" onplay="toggle_video(this.parentNode, true);" class="post_video"><source type="video/mp4" src="/post/0T5l0I4Gy/LyOfXIz.orig.mp4"/></video><div onclick="toggle_video(this.parentNode);" class="post_video_overlay post_video_overlay-paused"></div></div><div class="post_body"><p><span class="post_author">nikitonsky: </span>Excellent copywriting</p><p>Thx @boryskoretskyi for the video</p></div><p class="post_meta">January 12, 2020 // <a href="/post/0T5l0I4Gy">Hyperlink</a><a href="/post/0T5l0I4Gy/edit" class="post_meta_edit">Edit</a></p></div></div><div data-id="0T55BPZyY" class="post"><div class="post_side"><img src="/static/nikitonsky.jpg" class="post_avatar"/></div><div class="post_content"><div style="max-width:550px"><a href="/post/0T55BPZyY/LyEGN2b.orig.png" target="_blank" style="padding-bottom:87.72727272727273%" class="post_img post_img-fix"><img src="/post/0T55BPZyY/LyEGN2b.fit.jpeg"/></a></div><div class="post_body"><p><span class="post_author">nikitonsky: </span>Why the hell are Albums and Shared albums two different things? Why do I have to decide on creation whether I want a shared or normal album? Why moving to an album and moving to shared album are two separate options? What is so special about shared albums that they are not counted “Albums”?</p></div><p class="post_meta">January 10, 2020 // <a href="/post/0T55BPZyY">Hyperlink</a><a href="/post/0T55BPZyY/edit" class="post_meta_edit">Edit</a></p></div></div><div class="loader"><img src="/static/favicons/apple-touch-icon-152x152.png"/></div><footer><a href="https://twitter.com/nikitonsky">Nikita Prokopov</a>, <a href="https://twitter.com/freetonik">Rakhim Davletkaliyev</a>, <a href="https://grishaev.me/">Ivan Grishaev</a>, <a href="https://twitter.com/dmitriid">Dmitrii Dimandt</a>, <a href="https://twitter.com/UlyanovskUI">Andrei Voronin</a>. 2019. All fights retarded.</footer></body></html>

Grumpy Website