servel 0.26.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75f1adecf46ae4f4e27908dd3fbf9668bcd8f11bf984891dae8ee0c4c4ce4d86
4
- data.tar.gz: a60bafd99c0e34e664978a7972508b7f8808b04d3f6d59c70cf50bf640863278
3
+ metadata.gz: b9764905c7e72d90eecf301bf30c25c5542602d70df065803e18c03ab8353322
4
+ data.tar.gz: cf989ead1073528b04fc5c2c86d2f57ce37beace6c110fe40955c802390e4d58
5
5
  SHA512:
6
- metadata.gz: 4e517dbf1780afa748772644f336acef587e2b60ef25736936f2ac79673f363a4b97bfe59fed2eb559e14c6565ce8b24cd589a6e3c140f2d0002570e540846fd
7
- data.tar.gz: e78d33037f5aedd290eb798dfa80dbb0aa8886f8724da3ce3f7bc4d12e8b623b64480c57b0a79f81d2922488ded6ca4ef6cffad70d21bb14e90c9a8d0604eb2b
6
+ metadata.gz: ed18495a7e3c37f25fd22655f7eebd8e78e712782d3970f15a46b205cc9c5e92da2ddb884277cae0558043b66754dac9936fd8dfcbd9dd9333c324caed2931b3
7
+ data.tar.gz: fadfa698ea51f4c95deee988c4ecfbd8edfff80776cf406fb780b5551f0d0207826110d8058ec150af763422d16901bb2a17431d2111cce855bd0346dd30933a
@@ -1,14 +1,15 @@
1
1
  #controls
2
- #page-back.paginator ◀
3
- #page-back-10.paginator ◀◀
4
- #layout-mode.paginator ⤡
5
2
  #page-jump-listing.paginator 🔗 Listing
3
+ #layout-mode.paginator ⤡
4
+ #page-back-10.paginator ◀◀
6
5
  #page-next-10.paginator ▶▶
6
+ #page-back.paginator ◀
7
7
  #page-next.paginator ▶
8
8
  #content
9
- %img#image
10
- %video#video{controls: true}
11
- %audio#audio{controls: true}
12
- #text
13
- %a#text-anchor{href: '#'}
14
- #text-content
9
+ #scroller
10
+ %img#image
11
+ %video#video{controls: false, loop: true}
12
+ %audio#audio{controls: true}
13
+ #text
14
+ %a#text-anchor{href: '#'}
15
+ #text-content
@@ -16,6 +16,14 @@ body {
16
16
  user-select: none;
17
17
  }
18
18
 
19
+ .text-selectable {
20
+ -webkit-user-select: text;
21
+ -moz-user-select: text;
22
+ -khtml-user-select: text;
23
+ -ms-user-select: text;
24
+ user-select: text;
25
+ }
26
+
19
27
  a {
20
28
  text-decoration: none;
21
29
  }
@@ -1,25 +1,85 @@
1
1
  #gallery {
2
2
  background: #333;
3
3
  display: none;
4
- flex-direction: column;
5
4
  }
6
5
 
7
6
  body.has-gallery.gallery #gallery {
8
7
  display: flex;
9
8
  }
10
9
 
10
+ #controls {
11
+ display: flex;
12
+ }
13
+
14
+ #page-jump-listing {
15
+ flex-grow: 1;
16
+ }
17
+
18
+ .paginator {
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ height: 75px;
23
+
24
+ font-size: 2em;
25
+ font-weight: bold;
26
+ text-align: center;
27
+ background-color: #1f1f1f;
28
+ color: #858585;
29
+
30
+ cursor: pointer;
31
+ }
32
+
33
+ .paginator:hover {
34
+ background-color: #0f0f0f;
35
+ color: #c1c1c1;
36
+ }
37
+
11
38
  #content {
12
39
  display: flex;
13
40
  align-items: center;
14
41
  justify-content: center;
15
42
  flex-grow: 1;
43
+ min-width: 0;
44
+ min-height: 0;
45
+ }
46
+
47
+ #scroller {
48
+ width: 100%;
49
+ max-height: 100%;
50
+ overflow: auto;
51
+ }
52
+
53
+ body.portrait #gallery {
54
+ flex-direction: column;
55
+ }
56
+
57
+ body.portrait .paginator {
58
+ width: 100px;
59
+ }
60
+
61
+ body.portrait #page-jump-listing {
62
+ width: auto;
63
+ }
64
+
65
+ body.landscape #gallery {
66
+ flex-direction: row;
67
+ }
68
+
69
+ body.landscape #controls {
70
+ flex-direction: column;
71
+ flex-shrink: 0;
72
+ width: 100px;
73
+ }
74
+
75
+ body.landscape #page-jump-listing {
76
+ writing-mode: vertical-rl;
77
+ transform: rotate(180deg);
16
78
  }
17
79
 
18
80
  #image, #video, #audio, #text {
19
81
  display: none;
20
- max-width: 100%;
21
82
  margin: 0 auto 0 auto;
22
- padding-top: 75px;
23
83
  }
24
84
 
25
85
  #video:focus, #audio:focus {
@@ -51,36 +111,6 @@ body.has-gallery.gallery #gallery {
51
111
  display: block;
52
112
  }
53
113
 
54
- #controls {
55
- position: fixed;
56
- left: 0;
57
- right: 0;
58
- display: flex;
59
- z-index: 10;
60
- }
61
-
62
- .paginator {
63
- display: flex;
64
- align-items: center;
65
- justify-content: center;
66
- width: 100px;
67
- height: 75px;
68
-
69
- font-size: 2em;
70
- font-weight: bold;
71
- text-align: center;
72
- background-color: #000000;
73
- color: #ffffff;
74
-
75
- opacity: 0.4;
76
- cursor: pointer;
77
- }
78
-
79
- #page-jump-listing {
80
- flex-grow: 1;
81
- width: auto;
82
- }
83
-
84
114
  @media screen and (max-width: 767px) {
85
115
  #gallery.video, #gallery.audio, #gallery.text {
86
116
  padding: 0;
@@ -101,9 +131,3 @@ body.has-gallery.gallery #gallery {
101
131
  display: none;
102
132
  }
103
133
  }
104
-
105
- @media screen and (min-width: 768px) {
106
- .paginator:hover {
107
- opacity: 0.7;
108
- }
109
- }
@@ -1,9 +1,13 @@
1
1
  "use strict";
2
2
 
3
3
  var Gallery = (function() {
4
- var LAYOUT_MODES = ["fit-both", "fit-width", "clamp-width"];
4
+ var LAYOUT_MODES = ["fit-both", "fit-width", "clamp-width", "full-size"];
5
5
 
6
+ var $body;
6
7
  var $gallery;
8
+ var $image;
9
+ var $video;
10
+ var $audio;
7
11
  var currentIndex;
8
12
  var layoutModeIndex = 0;
9
13
 
@@ -20,9 +24,10 @@ var Gallery = (function() {
20
24
 
21
25
  function clearContent() {
22
26
  $gallery.classList.remove("image", "video", "audio", "text");
23
- $("#image").src = "about:none";
24
- $("#video").src = "about:none";
25
- $("#audio").src = "about:none";
27
+ $video.removeAttribute('src');
28
+ $video.pause();
29
+ $audio.removeAttribute('src');
30
+ $audio.pause();
26
31
  $("#text-content").innerHTML = "";
27
32
  }
28
33
 
@@ -97,6 +102,11 @@ var Gallery = (function() {
97
102
  if(layoutModeIndex >= LAYOUT_MODES.length) layoutModeIndex = 0;
98
103
  }
99
104
 
105
+ function playPauseVideo() {
106
+ if ($video.paused || $video.ended) $video.play();
107
+ else $video.pause();
108
+ }
109
+
100
110
  function initEvents() {
101
111
  document.body.addEventListener("click", function(e) {
102
112
  if(!e.target) return;
@@ -118,7 +128,7 @@ var Gallery = (function() {
118
128
  fastForward();
119
129
  }
120
130
  else if(e.target.matches("#page-jump-listing")) {
121
- e.preventDefault();
131
+ e.stopPropagation();
122
132
  Index.jumpListing();
123
133
  }
124
134
  else if(e.target.closest("#layout-mode")) {
@@ -126,6 +136,10 @@ var Gallery = (function() {
126
136
  switchLayoutMode();
127
137
  layout();
128
138
  }
139
+ else if(e.target.matches("#video")) {
140
+ e.stopPropagation();
141
+ playPauseVideo();
142
+ }
129
143
  });
130
144
 
131
145
  window.addEventListener("keydown", function(e) {
@@ -143,19 +157,42 @@ var Gallery = (function() {
143
157
  }
144
158
 
145
159
  function layout() {
146
- var viewportHeight = document.documentElement.clientHeight + "px";
147
- $gallery.style.minHeight = viewportHeight;
160
+ var vw = document.documentElement.clientWidth;
161
+ var vh = document.documentElement.clientHeight;
162
+
163
+ var viewportOrientation = vw > vh ? "landscape" : "portrait";
164
+ $body.classList.remove("landscape", "portrait");
165
+ $body.classList.add(viewportOrientation);
166
+
167
+ $gallery.style.height = vh + "px";
168
+
169
+ var scrollerMaxHeight = viewportOrientation == "landscape" ? vh : vh - 75;
148
170
 
149
171
  var layoutMode = LAYOUT_MODES[layoutModeIndex];
150
- var maxHeight = layoutMode == "fit-both" ? viewportHeight : "none";
151
- var maxWidth = layoutMode == "clamp-width" ? "1000px" : "100%";
152
172
 
153
- $("#image").style.maxWidth = maxWidth;
154
- $("#image").style.maxHeight = maxHeight;
155
- $("#video").style.maxWidth = maxWidth;
156
- $("#video").style.maxHeight = maxHeight;
157
- $("#audio").style.maxWidth = maxWidth;
158
- $("#audio").style.maxHeight = maxHeight;
173
+ if(layoutMode == "fit-both") {
174
+ var maxWidth = "100%";
175
+ var maxHeight = (scrollerMaxHeight + "px");
176
+ }
177
+ else if(layoutMode == "fit-width") {
178
+ var maxWidth = "100%";
179
+ var maxHeight = "none";
180
+ }
181
+ else if(layoutMode == "clamp-width") {
182
+ var maxWidth = "1000px";
183
+ var maxHeight = "none";
184
+ }
185
+ else if(layoutMode == "full-size") {
186
+ var maxWidth = "none";
187
+ var maxHeight = "none";
188
+ }
189
+
190
+ $image.style.maxWidth = maxWidth;
191
+ $image.style.maxHeight = maxHeight;
192
+ $video.style.maxWidth = maxWidth;
193
+ $video.style.maxHeight = maxHeight;
194
+ $audio.style.maxWidth = maxWidth;
195
+ $audio.style.maxHeight = maxHeight;
159
196
  }
160
197
 
161
198
  function initLayout() {
@@ -169,7 +206,11 @@ var Gallery = (function() {
169
206
  }
170
207
 
171
208
  function init() {
209
+ $body = $("body");
172
210
  $gallery = $("#gallery");
211
+ $image = $("#image");
212
+ $video = $("#video");
213
+ $audio = $("#audio");
173
214
 
174
215
  onEntriesUpdate();
175
216
 
@@ -19,52 +19,8 @@ var Index = (function() {
19
19
  document.body.classList.add("gallery");
20
20
  }
21
21
 
22
- function jumpScroll() {
23
- if(galleryVisible()) {
24
- jumpListing();
25
- window.scrollTo(0, 0);
26
- }
27
- else {
28
- jumpGallery();
29
- window.scrollTo(0, document.body.scrollHeight);
30
- }
31
- }
32
-
33
- function atTop() {
34
- return window.scrollY == 0;
35
- }
36
-
37
- function bottomScrollDown(event) {
38
- return galleryVisible() && atBottom() && event.deltaY > 0;
39
- }
40
-
41
- function topScrollUp(event) {
42
- return listingVisible() && atTop() && event.deltaY < 0;
43
- }
44
-
45
- function initEvents() {
46
- var scrollSize = 0;
47
-
48
- window.addEventListener("wheel", function(event) {
49
- if(bottomScrollDown(event) || topScrollUp(event)) {
50
- scrollSize += Math.abs(event.deltaY);
51
-
52
- if(scrollSize >= 1500) {
53
- scrollSize = 0;
54
- jumpScroll();
55
- }
56
- }
57
- else {
58
- scrollSize = 0;
59
- }
60
- });
61
- }
62
-
63
22
  function init() {
64
- if((Entries.media().length / Entries.all().length) >= 0.5) jumpGallery();
65
- else jumpListing();
66
-
67
- initEvents();
23
+ jumpListing();
68
24
  }
69
25
 
70
26
  return {
@@ -27,7 +27,7 @@ var Listing = (function() {
27
27
  function renderRow(file) {
28
28
  return HTMLSafe`
29
29
  <tr>
30
- <td class="name">
30
+ <td class="name text-selectable">
31
31
  <span class="icon">${file.icon}</span>
32
32
  <a href="${file.href}" class="default ${file.class}" data-url="${file.href}" data-type="${file.mediaType}">${file.name}</a>
33
33
  </td>
data/bin/servel CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require "servel"
4
4
 
5
- Servel::CLI.new(ARGV).start
5
+ Servel::CLI.new.start
@@ -3,6 +3,7 @@ require 'rack/handler/puma'
3
3
  require 'hamlit'
4
4
  require 'active_support/all'
5
5
  require 'lru_redux'
6
+ require 'tty-config'
6
7
 
7
8
  require 'thread'
8
9
  require 'pathname'
@@ -15,6 +16,10 @@ module Servel
15
16
 
16
17
  Rack::URLMap.new(url_map)
17
18
  end
19
+
20
+ def self.config
21
+ @config ||= Servel::ConfigParser.new.config
22
+ end
18
23
  end
19
24
 
20
25
  require "servel/version"
@@ -25,4 +30,5 @@ require "servel/haml_context"
25
30
  require "servel/index"
26
31
  require "servel/app"
27
32
  require "servel/home_app"
33
+ require "servel/config_parser"
28
34
  require "servel/cli"
@@ -1,18 +1,14 @@
1
- class Servel::CLI
2
- def initialize(argv)
3
- @argv = argv
4
- end
5
-
6
- def start
7
- Rack::Handler::Puma.run(Servel.build_app(path_map))
8
- end
9
-
10
- def path_map
11
- @argv.map do |arg|
12
- root, url_root = arg.split(":" , 2)
13
- root = Pathname.new(root).realpath
14
-
15
- [root, url_root || "/"]
16
- end.to_h
17
- end
18
- end
1
+ class Servel::CLI
2
+ def start
3
+ Rack::Handler::Puma.run(Servel.build_app(path_map))
4
+ end
5
+
6
+ def path_map
7
+ Servel.config.fetch(:listings).map do |listing|
8
+ listing = { listing => nil } if listing.is_a?(String)
9
+
10
+ root, url_root = listing.keys.first, listing.values.first || "/"
11
+ [Pathname.new(root).realpath, url_root]
12
+ end.to_h
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ class Servel::ConfigParser
2
+ attr_reader :config
3
+
4
+ def initialize
5
+ @config = TTY::Config.new
6
+ @config.filename = "servel"
7
+ @config.append_path(Dir.pwd)
8
+ @config.append_path((Pathname.new(Dir.home) + ".servel").to_s)
9
+ @config.append_path(Dir.home)
10
+ @config.env_prefix = "servel"
11
+ @config.autoload_env
12
+ @config.read if @config.exist?
13
+
14
+ @config.append(*parse_argv, to: :listings)
15
+ end
16
+
17
+ def parse_argv
18
+ ARGV.map do |arg|
19
+ root, url_root = arg.split(":" , 2)
20
+ { root => url_root }
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Servel
2
- VERSION = "0.26.0"
2
+ VERSION = "0.31.0"
3
3
  end
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency "hamlit"
29
29
  spec.add_dependency "activesupport"
30
30
  spec.add_dependency "lru_redux"
31
+ spec.add_dependency "tty-config"
31
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: servel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.0
4
+ version: 0.31.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brenton "B-Train" Fletcher
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-12 00:00:00.000000000 Z
11
+ date: 2020-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: tty-config
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Serves files and directories over HTTP.
112
126
  email:
113
127
  - i@bloople.net
@@ -143,6 +157,7 @@ files:
143
157
  - lib/servel.rb
144
158
  - lib/servel/app.rb
145
159
  - lib/servel/cli.rb
160
+ - lib/servel/config_parser.rb
146
161
  - lib/servel/entry.rb
147
162
  - lib/servel/entry_factory.rb
148
163
  - lib/servel/haml_context.rb
@@ -170,8 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
170
185
  - !ruby/object:Gem::Version
171
186
  version: '0'
172
187
  requirements: []
173
- rubyforge_project:
174
- rubygems_version: 2.7.6
188
+ rubygems_version: 3.0.3
175
189
  signing_key:
176
190
  specification_version: 4
177
191
  summary: Serves files and directories over HTTP.