voterunner

quick and dirty votes and discussions
git clone https://git.ce9e.org/voterunner.git

commit
4f9527a5ebcc7678543d42c9a63b61b3f014f2c8
parent
6c4c3a6a632958c99d8e3aaed8a73ff1cdd52ce4
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2017-11-18 11:37
refactor css

Diffstat

M static/scss/bar.scss 32 ++++++++++++++++++++------------
M static/scss/base.scss 2 +-
M static/scss/layout.scss 4 ++--
M static/scss/tree.scss 90 ++++++++++++++++++++++++++++++------------------------------
M static/scss/user.scss 41 ++++++++++-------------------------------
M static/src/voterunner.js 48 ++++++++++++++++++++++++------------------------
M tpl/app.html 18 +++++++++---------

7 files changed, 111 insertions, 124 deletions


diff --git a/static/scss/bar.scss b/static/scss/bar.scss

@@ -1,4 +1,16 @@
    1    -1 %bar-button {
   -1     1 .bar {
   -1     2 	display: flex;
   -1     3 }
   -1     4 
   -1     5 .bar__item {
   -1     6 	padding: $padding;
   -1     7 	white-space: nowrap;
   -1     8 	overflow: hidden;
   -1     9 	text-overflow: ellipsis;
   -1    10 	flex: 0 0 auto;
   -1    11 }
   -1    12 
   -1    13 .bar__item--button {
    2    14 	appearance: none;
    3    15 	background: none;
    4    16 	border: 0;
@@ -7,6 +19,7 @@
    7    19 	color: inherit;
    8    20 	text-align: center;
    9    21 
   -1    22 	&:focus,
   10    23 	&:hover {
   11    24 		background-color: rgba($color-bg, 0.2);
   12    25 	}
@@ -16,21 +29,16 @@
   16    29 	}
   17    30 }
   18    31 
   19    -1 %bar-item {
   20    -1 	padding: $padding;
   21    -1 	white-space: nowrap;
   22    -1 	overflow: hidden;
   23    -1 	text-overflow: ellipsis;
   -1    32 .bar__item--grow {
   -1    33 	flex: 1 1 auto;
   24    34 }
   25    35 
   26    -1 %bar-item-left {
   27    -1 	@extend %bar-item;
   28    -1 	float: left;
   -1    36 .bar__item--left {
   29    37 	border-right: 1px solid $color-border;
   -1    38 	order: 0;
   30    39 }
   31    40 
   32    -1 %bar-item-right {
   33    -1 	@extend %bar-item;
   34    -1 	float: right;
   -1    41 .bar__item--right {
   35    42 	border-left: 1px solid $color-border;
   -1    43 	order: 100;
   36    44 }

diff --git a/static/scss/base.scss b/static/scss/base.scss

@@ -4,7 +4,7 @@
    4     4 
    5     5 input[type="text"],
    6     6 textarea {
    7    -1 	background: $color-bg;
   -1     7 	background-color: $color-bg;
    8     8 }
    9     9 
   10    10 textarea {

diff --git a/static/scss/layout.scss b/static/scss/layout.scss

@@ -46,8 +46,8 @@ body > header {
   46    46 }
   47    47 
   48    48 #tree,
   49    -1 #user,
   50    -1 #tree .node .body {
   -1    49 .user,
   -1    50 .node__body {
   51    51 	border: 1px solid $color-border;
   52    52 	border-radius: ($padding / 2) ($padding / 2) 0 0;
   53    53 }

diff --git a/static/scss/tree.scss b/static/scss/tree.scss

@@ -11,69 +11,69 @@
   11    11 .node {
   12    12 	margin: $spacer 0;
   13    13 
   14    -1 	&:target > .body {
   -1    14 	&:target > .node__body {
   15    15 		outline: 5px auto $color-link;
   16    16 		outline-offset: -2px;
   17    17 	}
   18    18 
   19    -1 	.body {
   20    -1 		background: $color-bg;
   21    -1 		break-inside: avoid;
   -1    19 	&.node--self > .node__body {
   -1    20 		.node__delegate {
   -1    21 			display: none;
   -1    22 		}
   22    23 
   23    -1 		@media print {
   24    -1 			border: 1px solid;
   -1    24 		.node__header {
   -1    25 			@media screen {
   -1    26 				background-color: $color-link;
   -1    27 				color: $color-bg;
   -1    28 			}
   -1    29 
   -1    30 			@media print {
   -1    31 				font-weight: bold;
   -1    32 			}
   25    33 		}
   26    34 	}
   27    35 
   28    -1 	.header {
   29    -1 		background: $color-bg-tint;
   -1    36 	&:not(.is-expanded) > .tree {
   -1    37 		display: none;
   30    38 	}
   31    39 
   32    -1 	.expand {
   33    -1 		@extend %bar-item-left;
   34    -1 		@extend %bar-button;
   -1    40 	&.is-expanded > .node__body {
   -1    41 		.node__expand:before {
   -1    42 			content: "v";
   -1    43 		}
   35    44 
   36    -1 		&:before {
   37    -1 			content: ">";
   -1    45 		.node__header {
   -1    46 			border-bottom: 1px solid $color-border;
   38    47 		}
   39    48 	}
   40    -1 	.name {
   41    -1 		@extend %bar-item;
   42    -1 	}
   43    -1 	.delegate {
   44    -1 		@extend %bar-item-right;
   45    -1 		@extend %bar-button;
   46    -1 	}
   47    -1 	.votes {
   48    -1 		@extend %bar-item-right;
   49    -1 	}
   -1    49 }
   50    50 
   51    -1 	.comment {
   52    -1 		padding: $padding;
   -1    51 .node__body {
   -1    52 	background: $color-bg;
   -1    53 	break-inside: avoid;
   -1    54 }
   53    55 
   54    -1 		> :first-child {
   55    -1 			margin-top: 0;
   56    -1 		}
   57    -1 		> :last-child {
   58    -1 			margin-bottom: 0;
   59    -1 		}
   60    -1 	}
   -1    56 .node__header {
   -1    57 	background-color: $color-bg-tint;
   -1    58 }
   61    59 
   62    -1 	&.m-self > .body {
   63    -1 		.delegate {
   64    -1 			display: none;
   65    -1 		}
   66    -1 		.header {
   67    -1 			background: $color-link;
   68    -1 			color: $color-bg;
   69    -1 		}
   -1    60 .node__expand {
   -1    61 	&:before {
   -1    62 		content: ">";
   70    63 	}
   -1    64 }
   71    65 
   72    -1 	&:not(.is-expanded) > .tree {
   73    -1 		display: none;
   74    -1 	}
   -1    66 .node__preview {
   -1    67 	opacity: 0.7;
   -1    68 }
   -1    69 
   -1    70 .node__comment {
   -1    71 	padding: $padding;
   75    72 
   76    -1 	&.is-expanded > .body .expand:before {
   77    -1 		content: "v";
   -1    73 	> :first-child {
   -1    74 		margin-top: 0;
   -1    75 	}
   -1    76 	> :last-child {
   -1    77 		margin-bottom: 0;
   78    78 	}
   79    79 }

diff --git a/static/scss/user.scss b/static/scss/user.scss

@@ -1,22 +1,8 @@
    1    -1 #user {
   -1     1 .user {
    2     2 	background: $color-bg-tint;
    3     3 
    4    -1 	.delegate {
    5    -1 		@extend %bar-item;
    6    -1 		float: left;
    7    -1 	}
    8    -1 
    9    -1 	.votes {
   10    -1 		@extend %bar-item-right;
   11    -1 	}
   12    -1 
   13    -1 	.undelegate {
   14    -1 		@extend %bar-item-right;
   15    -1 		@extend %bar-button;
   16    -1 
   17    -1 		&:before {
   18    -1 			content: "‒";
   19    -1 		}
   -1     4 	.bar {
   -1     5 		border-bottom: 1px solid $color-border;
   20     6 	}
   21     7 
   22     8 	@media print {
@@ -24,27 +10,20 @@
   24    10 	}
   25    11 }
   26    12 
   27    -1 .statusbar {
   28    -1 	width: 100%;
   29    -1 	border-bottom: 1px solid $color-border;
   30    -1 	overflow: hidden;
   -1    13 .user__undelegate {
   -1    14 	&:before {
   -1    15 		content: "‒";
   -1    16 	}
   31    17 }
   32    18 
   33    -1 #name {
   34    -1 	@extend %bar-item;
   35    -1 	float: left;
   36    -1 	max-width: 80%;  // TODO: prevent linebreak
   37    -1 
   -1    19 .user__name {
   38    20 	input {
   39    21 		font-size: 120%;
   40    22 		height: 1.6em;
   41    23 	}
   42    24 }
   43    25 
   44    -1 #rm {
   45    -1 	@extend %bar-item-right;
   46    -1 	@extend %bar-button;
   47    -1 
   -1    26 .user__rm {
   48    27 	font-size: 120%;
   49    28 	padding: $padding;
   50    29 	line-height: 1.6;
@@ -55,7 +34,7 @@
   55    34 	}
   56    35 }
   57    36 
   58    -1 #comment textarea {
   -1    37 .user__comment textarea {
   59    38 	width: 100%;
   60    39 	min-height: 15em;
   61    40 	border: none;

diff --git a/static/src/voterunner.js b/static/src/voterunner.js

@@ -90,7 +90,7 @@ var tplNode = function(nodes, node, ID) {
   90    90 		classList.push('is-expanded');
   91    91 	}
   92    92 	if (node.id === ID) {
   93    -1 		classList.push('m-self');
   -1    93 		classList.push('node--self');
   94    94 	}
   95    95 
   96    96 	var delegateAttrs = {};
@@ -106,26 +106,26 @@ var tplNode = function(nodes, node, ID) {
  106   106 		'aria-expanded': '' + !!node.expanded,
  107   107 	}, [
  108   108 		h('article', {
  109    -1 			className: 'body',
   -1   109 			className: 'node__body',
  110   110 		}, [
  111   111 			h('header', {
  112    -1 				className: 'header',
   -1   112 				className: 'node__header bar',
  113   113 			}, [
  114   114 				h('button', {
  115    -1 					className: 'expand',
   -1   115 					className: 'node__expand bar__item bar__item--button bar__item--left',
  116   116 					title: _(node.expanded ? 'collapse' : 'expand'),
  117   117 				}),
  118    -1 				h('div', {className: 'votes'}, '' + getVotes(nodes, node)),
  119   118 				h('button', {
  120    -1 					className: 'delegate',
   -1   119 					className: 'node__delegate bar__item bar__item--button bar__item--right',
  121   120 					title: _('delegate to ') + getName(node),
  122   121 					attributes: delegateAttrs,
  123   122 				}, '+'),
  124    -1 				h('div', {className: 'name'}, getName(node)),
  125    -1 				!node.expanded && node.comment && h('div', {className: 'preview'}, node.comment.substr(0, 100)),
   -1   123 				h('div', {className: 'node__votes bar__item bar__item--right'}, '' + getVotes(nodes, node)),
   -1   124 				h('div', {className: 'node__name bar__item' + (!node.expanded && node.comment ? '' : ' bar__item--grow')}, getName(node)),
   -1   125 				!node.expanded && node.comment && h('div', {className: 'node__preview bar__item bar__item--grow'}, node.comment.substr(0, 100)),
  126   126 			]),
  127   127 			node.expanded && h('div', {
  128    -1 				className: 'comment',
   -1   128 				className: 'node__comment',
  129   129 				dangerouslySetInnerHTML: {
  130   130 					__html: md.render(node.comment || '')
  131   131 				},
@@ -217,19 +217,19 @@ document.addEventListener('DOMContentLoaded', function() {
  217   217 		return node.id === ID;
  218   218 	});
  219   219 	if (user) {
  220    -1 		document.querySelector('#name input').value = user.name;
  221    -1 		document.querySelector('#comment textarea').value = user.comment;
   -1   220 		document.querySelector('.user__name input').value = user.name;
   -1   221 		document.querySelector('.user__comment textarea').value = user.comment;
  222   222 		ensureVisible(user);
  223   223 	}
  224   224 
  225   225 	var updateUser = function() {
  226    -1 		document.querySelector('#user .votes').textContent = getVotes(nodes, user || {});
   -1   226 		document.querySelector('.user__votes').textContent = getVotes(nodes, user || {});
  227   227 
  228   228 		if (user && user.delegate) {
  229   229 			var delegatee = getNode(user.delegate);
  230    -1 			document.querySelector('#user .delegate').textContent = _('delegated to: ') + getName(delegatee);
   -1   230 			document.querySelector('.user__delegation').textContent = _('delegated to: ') + getName(delegatee);
  231   231 		} else {
  232    -1 			document.querySelector('#user .delegate').textContent = _('(no delegation)');
   -1   232 			document.querySelector('.user__delegation').textContent = _('(no delegation)');
  233   233 		}
  234   234 	};
  235   235 
@@ -250,33 +250,33 @@ document.addEventListener('DOMContentLoaded', function() {
  250   250 	var update = initVDom(document.querySelector('#tree'), nodes, ID, function() {
  251   251 		updateUser();
  252   252 
  253    -1 		forEach(document.querySelectorAll('.expand'), function(element) {
   -1   253 		forEach(document.querySelectorAll('.node__expand'), function(element) {
  254   254 			element.addEventListener('click', toggleExpand);
  255   255 		});
  256   256 
  257    -1 		forEach(document.querySelectorAll('.delegate'), function(element) {
   -1   257 		forEach(document.querySelectorAll('.node__delegate'), function(element) {
  258   258 			element.addEventListener('click', setDelegate);
  259   259 		});
  260   260 	});
  261   261 
  262    -1 	document.querySelector('#rm').addEventListener('click', function(event) {
   -1   262 	document.querySelector('.user__rm').addEventListener('click', function(event) {
  263   263 		if (confirm(_("Do you really want to delete this opinion?"))) {
  264   264 			socket.emit('rmNode');
  265    -1 			document.querySelector('#name input').value = '';
  266    -1 			document.querySelector('#comment textarea').value = '';
   -1   265 			document.querySelector('.user__name input').value = '';
   -1   266 			document.querySelector('.user__comment textarea').value = '';
  267   267 		}
  268   268 	});
  269   269 
  270    -1 	document.querySelector('#name input').addEventListener('change', function(event) {
   -1   270 	document.querySelector('.user__name input').addEventListener('change', function(event) {
  271   271 		socket.emit('setNodeName', event.target.value);
  272   272 	});
  273   273 
  274    -1 	document.querySelector('.undelegate').addEventListener('click', function(event) {
   -1   274 	document.querySelector('.user__undelegate').addEventListener('click', function(event) {
  275   275 		socket.emit('rmDelegate');
  276   276 	});
  277   277 
  278   278 	var pushComment = throttle(function() {
  279    -1 		var comment = document.querySelector('#comment textarea').value;
   -1   279 		var comment = document.querySelector('.user__comment textarea').value;
  280   280 		var node = nodes.find(function(n) {
  281   281 			return n.id === ID;
  282   282 		});
@@ -287,8 +287,8 @@ document.addEventListener('DOMContentLoaded', function() {
  287   287 		}
  288   288 	}, 1000);
  289   289 
  290    -1 	document.querySelector('#comment textarea').addEventListener('change', pushComment);
  291    -1 	document.querySelector('#comment textarea').addEventListener('keydown', pushComment);
   -1   290 	document.querySelector('.user__comment textarea').addEventListener('change', pushComment);
   -1   291 	document.querySelector('.user__comment textarea').addEventListener('keydown', pushComment);
  292   292 
  293   293 	socket.on('rmNode', function(id) {
  294   294 		nodes = nodes.filter(function(node) {

diff --git a/tpl/app.html b/tpl/app.html

@@ -18,19 +18,19 @@
   18    18 
   19    19 	<div><div>
   20    20 		<div id="sidebar">
   21    -1 			<div id="user">
   22    -1 				<div class="statusbar">
   23    -1 					<div class="delegate">(no delegation)</div>
   24    -1 					<span class="votes" title="number of votes of you and all your followers">1</span>
   25    -1 					<button class="undelegate" title="revoke delegation"></button>
   -1    21 			<div class="user">
   -1    22 				<div class="bar">
   -1    23 					<div class="user__delegation bar__item bar__item--grow">(no delegation)</div>
   -1    24 					<span class="user__votes bar__item bar__item--right" title="number of votes of you and all your followers">1</span>
   -1    25 					<button class="user__undelegate bar__item bar__item--button bar__item--right" title="revoke delegation"></button>
   26    26 				</div>
   27    -1 				<div class="statusbar">
   28    -1 					<div id="name">
   -1    27 				<div class="bar">
   -1    28 					<div class="user__name bar__item bar__item--grow">
   29    29 						<input type="text" placeholder="<enter your name>" />
   30    30 					</div>
   31    -1 					<button id="rm" title="remove your opinion"></button>
   -1    31 					<button title="remove your opinion" class="user__rm bar__item bar__item--button bar__item--right"></button>
   32    32 				</div>
   33    -1 				<div id="comment">
   -1    33 				<div class="user__comment">
   34    34 					<textarea></textarea>
   35    35 				</div>
   36    36 			</div>