├── .gitignore
├── .jshintrc
├── README.md
├── app
├── app.js
├── index.html
├── js
│ └── lib
│ │ └── version.js
├── photon
│ ├── css
│ │ └── photon.css
│ └── fonts
│ │ ├── photon-entypo.eot
│ │ ├── photon-entypo.svg
│ │ ├── photon-entypo.ttf
│ │ └── photon-entypo.woff
├── style.css
└── template.html
├── build
├── background.png
├── icon.icns
└── icon.ico
├── images
└── icon.png
├── main.js
├── package.json
└── window.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "esversion": 6,
3 | "predef" : ["component", "window", "exports"]
4 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Electron image viewer
2 |
3 | A quick and dirty image viewer made in 8 hours over 5 days.
4 |
5 | Uses [Electron](https://github.com/electron/electron) + [Ractive](https://github.com/ractivejs/ractive) + [Photon](https://github.com/connors/photon/).
6 |
7 | Supports only those image formats supported by Chromium: JPG, PNG, GIF, BPM, WEBP and SVG.
8 |
9 | **Shortcuts**:
10 | * left and right arrow for previous/next image
11 | * "f" to toggle fullscreen
12 | * "n" to toggle filename display
13 | * "c" to toggle background color colorpicker
14 | * esc to exit fullscreen or quit the application
15 | * del or command+backspace to trash current image, hold shift for permanent deletion
16 |
17 | 
18 |
19 | A Turkish cat sleeping on a pile of books picture source: http://cuteoverload.com/2013/06/23/turkey-cat/
20 |
21 | The font used for the app icon is [SF Alien Encounters by ShyFoundry](http://shyfoundry.com/fonts/shareware/sfalienenc.html).
22 |
--------------------------------------------------------------------------------
/app/app.js:
--------------------------------------------------------------------------------
1 | const { remote, ipcRenderer, shell } = require("electron");
2 | const path = require("path");
3 | const Ractive = require("ractive");
4 | const ractiveEventsTap = require("ractive-events-tap");
5 | const jetpack = require("fs-jetpack");
6 | const Mousetrap = require("mousetrap");
7 | const Hamster = require("hamsterjs");
8 | const ElectronStore = require("electron-store");
9 | const trash = require("trash");
10 |
11 | const store = new ElectronStore();
12 |
13 | const displayableExtensions = [
14 | "jpg", "jpeg", "png", "gif", "webp", "bmp", "svg"
15 | ];
16 |
17 | const cwd = remote.process.cwd();
18 | const inputArgs = remote.process.argv;
19 | const inputPath = inputArgs.pop();
20 | const templatePath = path.join(__dirname, "template.html");
21 | const templateString = jetpack.read(templatePath);
22 |
23 | const app = new Ractive({
24 | el: "#viewer",
25 | template: templateString,
26 |
27 | events: {
28 | tap: ractiveEventsTap,
29 | },
30 |
31 | data() {
32 | return {
33 | backgroundColor: "#f8f8f8",
34 | colorPickerVisible: false,
35 | displayFileName: true,
36 | currentIndex: 0,
37 | files: [],
38 | };
39 | },
40 |
41 | computed: {
42 | currentImage() {
43 | const files = this.get("files");
44 | const currentIndex = this.get("currentIndex");
45 |
46 | return files[currentIndex] || "";
47 | },
48 |
49 | previousButtonHidden(){
50 | return !this.hasPreviousImage() ? "hidden" : "";
51 | },
52 |
53 | nextButtonHidden(){
54 | return !this.hasNextImage() ? "hidden" : "";
55 | }
56 | },
57 |
58 | onconfig() {
59 | const self = this;
60 |
61 | this.toggleColorPicker = this.toggleColorPicker.bind(this);
62 | this.toggleFullscreen = this.toggleFullscreen.bind(this);
63 | this.handleMouseWheel = this.handleMouseWheel.bind(this);
64 | this.savePreferences = this.savePreferences.bind(this);
65 | this.toggleFilename = this.toggleFilename.bind(this);
66 | this.deleteFile = this.deleteFile.bind(this);
67 | this.trashFile = this.trashFile.bind(this);
68 |
69 | this.loadPreferences();
70 |
71 | this.on({
72 | input(ctx, data) {
73 | const { files, index } = this.parseInput(data);
74 |
75 | this.set("files", files);
76 | this.set("currentIndex", index);
77 | },
78 |
79 | previousImage() {
80 | if (this.hasPreviousImage()) {
81 | this.subtract("currentIndex");
82 | }
83 | },
84 |
85 | nextImage() {
86 | if (this.hasNextImage()) {
87 | this.add("currentIndex");
88 | }
89 | },
90 |
91 | escape() {
92 | if (this.get("colorPickerVisible")) {
93 | this.toggle("colorPickerVisible");
94 | } else if (this.get("maximized")) {
95 | ipcRenderer.send("unmaximize");
96 | } else {
97 | ipcRenderer.send("quit");
98 | }
99 | },
100 | });
101 |
102 | Mousetrap.bind(["left"], () => this.fire("previousImage"));
103 | Mousetrap.bind(["right"], () => this.fire("nextImage"));
104 | Mousetrap.bind(["escape"], () => this.fire("escape"));
105 |
106 | Mousetrap.bind(["b"], () => this.setBackgroundColor("#000000"));
107 | Mousetrap.bind(["w"], () => this.setBackgroundColor("#ffffff"));
108 | Mousetrap.bind(["g"], () => this.setBackgroundColor("#888888"));
109 |
110 | Mousetrap.bind(["f"], this.toggleFullscreen);
111 | Mousetrap.bind(["n"], this.toggleFilename);
112 | Mousetrap.bind(["c"], this.toggleColorPicker);
113 |
114 | Mousetrap.bind(["del", "command+backspace"], this.trashFile);
115 | Mousetrap.bind(["shift+del", "shift+command+backspace"], this.deleteFile);
116 |
117 | Hamster(document).wheel(this.handleMouseWheel);
118 |
119 | this.fire("input", inputPath);
120 | },
121 |
122 | loadPreferences() {
123 | const {
124 | backgroundColor,
125 | displayFileName,
126 | } = store.get();
127 |
128 | if (backgroundColor) {
129 | this.set({ backgroundColor} );
130 | }
131 |
132 | if (typeof displayFileName === "boolean") {
133 | this.set({ displayFileName });
134 | }
135 | },
136 |
137 | calculateNextIndex(currentIndex) {
138 | const files = this.get("files");
139 | const len = files.length;
140 | const isLastImage = (currentIndex === len-1);
141 | const isFirstImage = (currentIndex === 0);
142 |
143 | let nextIndex = currentIndex;
144 |
145 | if (isLastImage) {
146 | nextIndex = currentIndex - 1;
147 | } else if (isFirstImage) {
148 | nextIndex = 0;
149 | }
150 |
151 | return nextIndex;
152 | },
153 |
154 | trashFile() {
155 | if (confirm("Move current file to trash/recycle bin?")) {
156 | this._deleteFile(false);
157 | }
158 | },
159 |
160 | deleteFile() {
161 | if (confirm("Permanently delete current file?")) {
162 | this._deleteFile("permanent");
163 | }
164 | },
165 |
166 | _deleteFile(permanent = false) {
167 | const currentImage = this.get("currentImage");
168 | const currentIndex = this.get("currentIndex");
169 | const nextIndex = this.calculateNextIndex(currentIndex);
170 | const deleter = permanent ? jetpack.removeAsync : trash;
171 |
172 | deleter(currentImage).then((data) => {
173 | this.splice("files", currentIndex, 1);
174 | this.set("currentIndex", nextIndex);
175 | });
176 | },
177 |
178 | setBackgroundColor(color) {
179 | this.set("backgroundColor", color);
180 | },
181 |
182 | savePreferences(w) {
183 | const { backgroundColor, displayFileName } = this.get();
184 |
185 | store.set({
186 | backgroundColor,
187 | displayFileName,
188 | });
189 | },
190 |
191 | toggleColorPicker() {
192 | this.toggle("colorPickerVisible");
193 | },
194 |
195 | parseInput(inputPath = "", dir = cwd) {
196 | if (!path.isAbsolute(inputPath)) {
197 | inputPath = path.resolve(dir, inputPath);
198 | }
199 |
200 | let files = [];
201 | let index = 0;
202 | let inputFile = "";
203 | let inputDir = inputPath;
204 |
205 | if (jetpack.exists(inputPath)) {
206 | if (this.isDisplayableImage(inputPath)) {
207 | inputFile = path.basename(inputPath);
208 | inputDir = path.dirname(inputPath);
209 | }
210 |
211 | if (this.isDirectory(inputDir)) {
212 | files = jetpack.list(inputDir)
213 | .filter(this.isDisplayableImage)
214 | .map((fileName) => path.join(inputDir, fileName));
215 | }
216 |
217 | if (files.length && inputFile) {
218 | index = files.indexOf(path.join(inputDir, inputFile));
219 | }
220 | }
221 |
222 | return {
223 | files: files.map(this.slash).map(this.encodeChars),
224 | index: index
225 | };
226 | },
227 |
228 | isDisplayableImage(inputPath) {
229 | const ext = path.extname(inputPath).slice(1);
230 | return ext && displayableExtensions.indexOf(ext) > -1;
231 | },
232 |
233 | isDirectory(inputPath) {
234 | return jetpack.exists(inputPath) === "dir";
235 | },
236 |
237 | slash(str) {
238 | return str.replace(/\\/g, "/");
239 | },
240 |
241 | encodeChars(str) {
242 | return str.replace(/\s/g, "%20");
243 | },
244 |
245 | handleMouseWheel(e, d, dx, dy){
246 | const cmd = (dy === 1) ? "previousImage" : "nextImage";
247 |
248 | this.fire(cmd);
249 | },
250 |
251 | toggleFullscreen() {
252 | const maximized = this.get("maximized");
253 | const cmd = maximized ? "unmaximize" : "maximize";
254 |
255 | ipcRenderer.send(cmd);
256 | },
257 |
258 | toggleFilename() {
259 | this.toggle("displayFileName");
260 | },
261 |
262 | hasNextImage() {
263 | const i = this.get("currentIndex");
264 | const files = this.get("files");
265 | const len = files.length - 1;
266 |
267 | return i < len;
268 | },
269 |
270 | hasPreviousImage() {
271 | const i = this.get("currentIndex");
272 |
273 | return i > 0;
274 | }
275 | });
276 |
277 |
278 |
279 | remote.getCurrentWindow().on("close", app.savePreferences);
280 |
281 |
282 |
283 | /* Handle messages from BrowserWindow processes */
284 | ipcRenderer.on("maximize", () => {
285 | app.set("maximized", true);
286 | });
287 |
288 | ipcRenderer.on("unmaximize", () => {
289 | app.set("maximized", false);
290 | });
291 |
292 |
293 |
294 | /* Drag&drop to open a file/folder */
295 | document.ondragover = document.ondrop = (e) => {
296 | e.preventDefault();
297 | };
298 |
299 | document.ondragover = (e) => {
300 | e.preventDefault();
301 | app.set("dragover", true);
302 | };
303 |
304 | document.ondragleave = document.ondragexit = document.ondragend = (e) => {
305 | e.preventDefault();
306 | app.set("dragover", false);
307 | };
308 |
309 | document.body.ondrop = (e) => {
310 | e.preventDefault();
311 |
312 | const inputPath = e.dataTransfer.files[0].path;
313 |
314 | app.fire("input", inputPath);
315 | app.set("dragover", false);
316 | };
317 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SVG Viewer
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/js/lib/version.js:
--------------------------------------------------------------------------------
1 | // generated by genversion
2 | module.exports = '0.3.0';
3 |
--------------------------------------------------------------------------------
/app/photon/css/photon.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * =====================================================
3 | * Photon v0.1.2
4 | * Copyright 2015 Connor Sears
5 | * Licensed under MIT (https://github.com/connors/proton/blob/master/LICENSE)
6 | *
7 | * v0.1.2 designed by @connors.
8 | * =====================================================
9 | */
10 |
11 | @charset "UTF-8";
12 | audio,
13 | canvas,
14 | progress,
15 | video {
16 | vertical-align: baseline;
17 | }
18 |
19 | audio:not([controls]) {
20 | display: none;
21 | }
22 |
23 | a:active,
24 | a:hover {
25 | outline: 0;
26 | }
27 |
28 | abbr[title] {
29 | border-bottom: 1px dotted;
30 | }
31 |
32 | b,
33 | strong {
34 | font-weight: bold;
35 | }
36 |
37 | dfn {
38 | font-style: italic;
39 | }
40 |
41 | h1 {
42 | font-size: 2em;
43 | margin: 0.67em 0;
44 | }
45 |
46 | small {
47 | font-size: 80%;
48 | }
49 |
50 | sub,
51 | sup {
52 | font-size: 75%;
53 | line-height: 0;
54 | position: relative;
55 | vertical-align: baseline;
56 | }
57 |
58 | sup {
59 | top: -0.5em;
60 | }
61 |
62 | sub {
63 | bottom: -0.25em;
64 | }
65 |
66 | pre {
67 | overflow: auto;
68 | }
69 |
70 | code,
71 | kbd,
72 | pre,
73 | samp {
74 | font-family: monospace, monospace;
75 | font-size: 1em;
76 | }
77 |
78 | button,
79 | input,
80 | optgroup,
81 | select,
82 | textarea {
83 | color: inherit;
84 | font: inherit;
85 | margin: 0;
86 | }
87 |
88 | input[type="number"]::-webkit-inner-spin-button,
89 | input[type="number"]::-webkit-outer-spin-button {
90 | height: auto;
91 | }
92 |
93 | input[type="search"] {
94 | -webkit-appearance: textfield;
95 | box-sizing: content-box;
96 | }
97 |
98 | input[type="search"]::-webkit-search-cancel-button,
99 | input[type="search"]::-webkit-search-decoration {
100 | -webkit-appearance: none;
101 | }
102 |
103 | fieldset {
104 | border: 1px solid #c0c0c0;
105 | margin: 0 2px;
106 | padding: 0.35em 0.625em 0.75em;
107 | }
108 |
109 | legend {
110 | border: 0;
111 | padding: 0;
112 | }
113 |
114 | table {
115 | border-collapse: collapse;
116 | border-spacing: 0;
117 | }
118 |
119 | td,
120 | th {
121 | padding: 0;
122 | }
123 |
124 | * {
125 | cursor: default;
126 | -webkit-user-drag: text;
127 | -webkit-user-select: none;
128 | -webkit-box-sizing: border-box;
129 | box-sizing: border-box;
130 | }
131 |
132 | html {
133 | height: 100%;
134 | width: 100%;
135 | overflow: hidden;
136 | }
137 |
138 | body {
139 | height: 100%;
140 | padding: 0;
141 | margin: 0;
142 | font-family: system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", Helvetica, "Segoe UI", sans-serif;
143 | font-size: 13px;
144 | line-height: 1.6;
145 | color: #333;
146 | background-color: transparent;
147 | }
148 |
149 | hr {
150 | margin: 15px 0;
151 | overflow: hidden;
152 | background: transparent;
153 | border: 0;
154 | border-bottom: 1px solid #ddd;
155 | }
156 |
157 | h1, h2, h3, h4, h5, h6 {
158 | margin-top: 20px;
159 | margin-bottom: 10px;
160 | font-weight: 500;
161 | white-space: nowrap;
162 | overflow: hidden;
163 | text-overflow: ellipsis;
164 | }
165 |
166 | h1 {
167 | font-size: 36px;
168 | }
169 |
170 | h2 {
171 | font-size: 30px;
172 | }
173 |
174 | h3 {
175 | font-size: 24px;
176 | }
177 |
178 | h4 {
179 | font-size: 18px;
180 | }
181 |
182 | h5 {
183 | font-size: 14px;
184 | }
185 |
186 | h6 {
187 | font-size: 12px;
188 | }
189 |
190 | .window {
191 | position: absolute;
192 | top: 0;
193 | right: 0;
194 | bottom: 0;
195 | left: 0;
196 | display: flex;
197 | flex-direction: column;
198 | background-color: #fff;
199 | }
200 |
201 | .window-content {
202 | position: relative;
203 | overflow-y: auto;
204 | display: flex;
205 | flex: 1;
206 | }
207 |
208 | .selectable-text {
209 | cursor: text;
210 | -webkit-user-select: text;
211 | }
212 |
213 | .text-center {
214 | text-align: center;
215 | }
216 |
217 | .text-right {
218 | text-align: right;
219 | }
220 |
221 | .text-left {
222 | text-align: left;
223 | }
224 |
225 | .pull-left {
226 | float: left;
227 | }
228 |
229 | .pull-right {
230 | float: right;
231 | }
232 |
233 | .padded {
234 | padding: 10px;
235 | }
236 |
237 | .padded-less {
238 | padding: 5px;
239 | }
240 |
241 | .padded-more {
242 | padding: 20px;
243 | }
244 |
245 | .padded-vertically {
246 | padding-top: 10px;
247 | padding-bottom: 10px;
248 | }
249 |
250 | .padded-vertically-less {
251 | padding-top: 5px;
252 | padding-bottom: 5px;
253 | }
254 |
255 | .padded-vertically-more {
256 | padding-top: 20px;
257 | padding-bottom: 20px;
258 | }
259 |
260 | .padded-horizontally {
261 | padding-right: 10px;
262 | padding-left: 10px;
263 | }
264 |
265 | .padded-horizontally-less {
266 | padding-right: 5px;
267 | padding-left: 5px;
268 | }
269 |
270 | .padded-horizontally-more {
271 | padding-right: 20px;
272 | padding-left: 20px;
273 | }
274 |
275 | .padded-top {
276 | padding-top: 10px;
277 | }
278 |
279 | .padded-top-less {
280 | padding-top: 5px;
281 | }
282 |
283 | .padded-top-more {
284 | padding-top: 20px;
285 | }
286 |
287 | .padded-bottom {
288 | padding-bottom: 10px;
289 | }
290 |
291 | .padded-bottom-less {
292 | padding-bottom: 5px;
293 | }
294 |
295 | .padded-bottom-more {
296 | padding-bottom: 20px;
297 | }
298 |
299 | .sidebar {
300 | background-color: #f5f5f4;
301 | }
302 |
303 | .draggable {
304 | -webkit-app-region: drag;
305 | }
306 |
307 | .clearfix:before, .clearfix:after {
308 | display: table;
309 | content: " ";
310 | }
311 | .clearfix:after {
312 | clear: both;
313 | }
314 |
315 | .btn {
316 | display: inline-block;
317 | padding: 3px 8px;
318 | margin-bottom: 0;
319 | font-size: 12px;
320 | line-height: 1.4;
321 | text-align: center;
322 | white-space: nowrap;
323 | vertical-align: middle;
324 | cursor: default;
325 | background-image: none;
326 | border: 1px solid transparent;
327 | border-radius: 4px;
328 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.06);
329 | -webkit-app-region: no-drag;
330 | }
331 | .btn:focus {
332 | outline: none;
333 | box-shadow: none;
334 | }
335 |
336 | .btn-mini {
337 | padding: 2px 6px;
338 | }
339 |
340 | .btn-large {
341 | padding: 6px 12px;
342 | }
343 |
344 | .btn-form {
345 | padding-right: 20px;
346 | padding-left: 20px;
347 | }
348 |
349 | .btn-default {
350 | color: #333;
351 | border-top-color: #c2c0c2;
352 | border-right-color: #c2c0c2;
353 | border-bottom-color: #a19fa1;
354 | border-left-color: #c2c0c2;
355 | background-color: #fcfcfc;
356 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fcfcfc), color-stop(100%, #f1f1f1));
357 | background-image: -webkit-linear-gradient(top, #fcfcfc 0%, #f1f1f1 100%);
358 | background-image: linear-gradient(to bottom, #fcfcfc 0%, #f1f1f1 100%);
359 | }
360 | .btn-default:active {
361 | background-color: #ddd;
362 | background-image: none;
363 | }
364 |
365 | .btn-primary,
366 | .btn-positive,
367 | .btn-negative,
368 | .btn-warning {
369 | color: #fff;
370 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
371 | }
372 |
373 | .btn-primary {
374 | border-color: #388df8;
375 | border-bottom-color: #0866dc;
376 | background-color: #6eb4f7;
377 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #6eb4f7), color-stop(100%, #1a82fb));
378 | background-image: -webkit-linear-gradient(top, #6eb4f7 0%, #1a82fb 100%);
379 | background-image: linear-gradient(to bottom, #6eb4f7 0%, #1a82fb 100%);
380 | }
381 | .btn-primary:active {
382 | background-color: #3e9bf4;
383 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3e9bf4), color-stop(100%, #0469de));
384 | background-image: -webkit-linear-gradient(top, #3e9bf4 0%, #0469de 100%);
385 | background-image: linear-gradient(to bottom, #3e9bf4 0%, #0469de 100%);
386 | }
387 |
388 | .btn-positive {
389 | border-color: #29a03b;
390 | border-bottom-color: #248b34;
391 | background-color: #5bd46d;
392 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bd46d), color-stop(100%, #29a03b));
393 | background-image: -webkit-linear-gradient(top, #5bd46d 0%, #29a03b 100%);
394 | background-image: linear-gradient(to bottom, #5bd46d 0%, #29a03b 100%);
395 | }
396 | .btn-positive:active {
397 | background-color: #34c84a;
398 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #34c84a), color-stop(100%, #248b34));
399 | background-image: -webkit-linear-gradient(top, #34c84a 0%, #248b34 100%);
400 | background-image: linear-gradient(to bottom, #34c84a 0%, #248b34 100%);
401 | }
402 |
403 | .btn-negative {
404 | border-color: #fb2f29;
405 | border-bottom-color: #fb1710;
406 | background-color: #fd918d;
407 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fd918d), color-stop(100%, #fb2f29));
408 | background-image: -webkit-linear-gradient(top, #fd918d 0%, #fb2f29 100%);
409 | background-image: linear-gradient(to bottom, #fd918d 0%, #fb2f29 100%);
410 | }
411 | .btn-negative:active {
412 | background-color: #fc605b;
413 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fc605b), color-stop(100%, #fb1710));
414 | background-image: -webkit-linear-gradient(top, #fc605b 0%, #fb1710 100%);
415 | background-image: linear-gradient(to bottom, #fc605b 0%, #fb1710 100%);
416 | }
417 |
418 | .btn-warning {
419 | border-color: #fcaa0e;
420 | border-bottom-color: #ee9d02;
421 | background-color: #fece72;
422 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fece72), color-stop(100%, #fcaa0e));
423 | background-image: -webkit-linear-gradient(top, #fece72 0%, #fcaa0e 100%);
424 | background-image: linear-gradient(to bottom, #fece72 0%, #fcaa0e 100%);
425 | }
426 | .btn-warning:active {
427 | background-color: #fdbc40;
428 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fdbc40), color-stop(100%, #ee9d02));
429 | background-image: -webkit-linear-gradient(top, #fdbc40 0%, #ee9d02 100%);
430 | background-image: linear-gradient(to bottom, #fdbc40 0%, #ee9d02 100%);
431 | }
432 |
433 | .btn .icon {
434 | float: left;
435 | width: 14px;
436 | height: 14px;
437 | margin-top: 1px;
438 | margin-bottom: 1px;
439 | color: #737475;
440 | font-size: 14px;
441 | line-height: 1;
442 | }
443 |
444 | .btn .icon-text {
445 | margin-right: 5px;
446 | }
447 |
448 | .btn-dropdown:after {
449 | font-family: "photon-entypo";
450 | margin-left: 5px;
451 | content: "";
452 | }
453 |
454 | .btn-group {
455 | position: relative;
456 | display: inline-block;
457 | vertical-align: middle;
458 | -webkit-app-region: no-drag;
459 | }
460 | .btn-group .btn {
461 | position: relative;
462 | float: left;
463 | }
464 | .btn-group .btn:focus, .btn-group .btn:active {
465 | z-index: 2;
466 | }
467 | .btn-group .btn.active {
468 | z-index: 3;
469 | }
470 |
471 | .btn-group .btn + .btn,
472 | .btn-group .btn + .btn-group,
473 | .btn-group .btn-group + .btn,
474 | .btn-group .btn-group + .btn-group {
475 | margin-left: -1px;
476 | }
477 | .btn-group > .btn:first-child {
478 | border-top-right-radius: 0;
479 | border-bottom-right-radius: 0;
480 | }
481 | .btn-group > .btn:last-child {
482 | border-top-left-radius: 0;
483 | border-bottom-left-radius: 0;
484 | }
485 | .btn-group > .btn:not(:first-child):not(:last-child) {
486 | border-radius: 0;
487 | }
488 | .btn-group .btn + .btn {
489 | border-left: 1px solid #c2c0c2;
490 | }
491 | .btn-group .btn + .btn.active {
492 | border-left: 0;
493 | }
494 | .btn-group .active {
495 | color: #fff;
496 | border: 1px solid transparent;
497 | background-color: #6d6c6d;
498 | background-image: none;
499 | }
500 | .btn-group .active .icon {
501 | color: #fff;
502 | }
503 |
504 | .toolbar {
505 | min-height: 22px;
506 | box-shadow: inset 0 1px 0 #f5f4f5;
507 | background-color: #e8e6e8;
508 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #e8e6e8), color-stop(100%, #d1cfd1));
509 | background-image: -webkit-linear-gradient(top, #e8e6e8 0%, #d1cfd1 100%);
510 | background-image: linear-gradient(to bottom, #e8e6e8 0%, #d1cfd1 100%);
511 | }
512 | .toolbar:before, .toolbar:after {
513 | display: table;
514 | content: " ";
515 | }
516 | .toolbar:after {
517 | clear: both;
518 | }
519 |
520 | .toolbar-header {
521 | border-bottom: 1px solid #c2c0c2;
522 | }
523 | .toolbar-header .title {
524 | margin-top: 1px;
525 | }
526 |
527 | .toolbar-footer {
528 | border-top: 1px solid #c2c0c2;
529 | -webkit-app-region: drag;
530 | }
531 |
532 | .title {
533 | margin: 0;
534 | font-size: 12px;
535 | font-weight: 400;
536 | text-align: center;
537 | color: #555;
538 | cursor: default;
539 | }
540 |
541 | .toolbar-borderless {
542 | border-top: 0;
543 | border-bottom: 0;
544 | }
545 |
546 | .toolbar-actions {
547 | margin-top: 4px;
548 | margin-bottom: 3px;
549 | padding-right: 3px;
550 | padding-left: 3px;
551 | padding-bottom: 3px;
552 | -webkit-app-region: drag;
553 | }
554 | .toolbar-actions:before, .toolbar-actions:after {
555 | display: table;
556 | content: " ";
557 | }
558 | .toolbar-actions:after {
559 | clear: both;
560 | }
561 | .toolbar-actions > .btn,
562 | .toolbar-actions > .btn-group {
563 | margin-left: 4px;
564 | margin-right: 4px;
565 | }
566 |
567 | label {
568 | display: inline-block;
569 | font-size: 13px;
570 | margin-bottom: 5px;
571 | white-space: nowrap;
572 | overflow: hidden;
573 | text-overflow: ellipsis;
574 | }
575 |
576 | input[type="search"] {
577 | box-sizing: border-box;
578 | }
579 |
580 | input[type="radio"],
581 | input[type="checkbox"] {
582 | margin: 4px 0 0;
583 | line-height: normal;
584 | }
585 |
586 | .form-control {
587 | display: inline-block;
588 | width: 100%;
589 | min-height: 25px;
590 | padding: 5px 10px;
591 | font-size: 13px;
592 | line-height: 1.6;
593 | background-color: #fff;
594 | border: 1px solid #ddd;
595 | border-radius: 4px;
596 | outline: none;
597 | }
598 | .form-control:focus {
599 | border-color: #6db3fd;
600 | box-shadow: 3px 3px 0 #6db3fd, -3px -3px 0 #6db3fd, -3px 3px 0 #6db3fd, 3px -3px 0 #6db3fd;
601 | }
602 |
603 | textarea {
604 | height: auto;
605 | }
606 |
607 | .form-group {
608 | margin-bottom: 10px;
609 | }
610 |
611 | .radio,
612 | .checkbox {
613 | position: relative;
614 | display: block;
615 | margin-top: 10px;
616 | margin-bottom: 10px;
617 | }
618 | .radio label,
619 | .checkbox label {
620 | padding-left: 20px;
621 | margin-bottom: 0;
622 | font-weight: normal;
623 | }
624 |
625 | .radio input[type="radio"],
626 | .radio-inline input[type="radio"],
627 | .checkbox input[type="checkbox"],
628 | .checkbox-inline input[type="checkbox"] {
629 | position: absolute;
630 | margin-left: -20px;
631 | margin-top: 4px;
632 | }
633 |
634 | .form-actions .btn {
635 | margin-right: 10px;
636 | }
637 | .form-actions .btn:last-child {
638 | margin-right: 0;
639 | }
640 |
641 | .pane-group {
642 | position: absolute;
643 | top: 0;
644 | right: 0;
645 | bottom: 0;
646 | left: 0;
647 | display: flex;
648 | }
649 |
650 | .pane {
651 | position: relative;
652 | overflow-y: auto;
653 | flex: 1;
654 | border-left: 1px solid #ddd;
655 | }
656 | .pane:first-child {
657 | border-left: 0;
658 | }
659 |
660 | .pane-sm {
661 | max-width: 220px;
662 | min-width: 150px;
663 | }
664 |
665 | .pane-mini {
666 | width: 80px;
667 | flex: none;
668 | }
669 |
670 | .pane-one-fourth {
671 | width: 25%;
672 | flex: none;
673 | }
674 |
675 | .pane-one-third {
676 | width: 33.3%;
677 | }
678 |
679 | img {
680 | -webkit-user-drag: text;
681 | }
682 |
683 | .img-circle {
684 | border-radius: 50%;
685 | }
686 |
687 | .img-rounded {
688 | border-radius: 4px;
689 | }
690 |
691 | .list-group {
692 | width: 100%;
693 | list-style: none;
694 | margin: 0;
695 | padding: 0;
696 | }
697 | .list-group * {
698 | margin: 0;
699 | white-space: nowrap;
700 | overflow: hidden;
701 | text-overflow: ellipsis;
702 | }
703 |
704 | .list-group-item {
705 | padding: 10px;
706 | font-size: 12px;
707 | color: #414142;
708 | border-top: 1px solid #ddd;
709 | }
710 | .list-group-item:first-child {
711 | border-top: 0;
712 | }
713 | .list-group-item.active, .list-group-item.selected {
714 | color: #fff;
715 | background-color: #116cd6;
716 | }
717 |
718 | .list-group-header {
719 | padding: 10px;
720 | }
721 |
722 | .media-object {
723 | margin-top: 3px;
724 | }
725 |
726 | .media-object.pull-left {
727 | margin-right: 10px;
728 | }
729 |
730 | .media-object.pull-right {
731 | margin-left: 10px;
732 | }
733 |
734 | .media-body {
735 | overflow: hidden;
736 | }
737 |
738 | .nav-group {
739 | font-size: 14px;
740 | }
741 |
742 | .nav-group-item {
743 | padding: 2px 10px 2px 25px;
744 | display: block;
745 | color: #333;
746 | text-decoration: none;
747 | white-space: nowrap;
748 | overflow: hidden;
749 | text-overflow: ellipsis;
750 | }
751 | .nav-group-item:active, .nav-group-item.active {
752 | background-color: #dcdfe1;
753 | }
754 | .nav-group-item .icon {
755 | width: 19px;
756 | height: 18px;
757 | float: left;
758 | color: #737475;
759 | margin-top: -3px;
760 | margin-right: 7px;
761 | font-size: 18px;
762 | text-align: center;
763 | }
764 |
765 | .nav-group-title {
766 | margin: 0;
767 | padding: 10px 10px 2px;
768 | font-size: 12px;
769 | font-weight: 500;
770 | color: #666666;
771 | }
772 |
773 | @font-face {
774 | font-family: "photon-entypo";
775 | src: url("../fonts/photon-entypo.eot");
776 | src: url("../fonts/photon-entypo.eot?#iefix") format("eot"), url("../fonts/photon-entypo.woff") format("woff"), url("../fonts/photon-entypo.ttf") format("truetype");
777 | font-weight: normal;
778 | font-style: normal;
779 | }
780 | .icon:before {
781 | position: relative;
782 | display: inline-block;
783 | font-family: "photon-entypo";
784 | speak: none;
785 | font-size: 100%;
786 | font-style: normal;
787 | font-weight: normal;
788 | font-variant: normal;
789 | text-transform: none;
790 | line-height: 1;
791 | -webkit-font-smoothing: antialiased;
792 | -moz-osx-font-smoothing: grayscale;
793 | }
794 |
795 | .icon-note:before {
796 | content: '\e800';
797 | }
798 |
799 | /* '' */
800 | .icon-note-beamed:before {
801 | content: '\e801';
802 | }
803 |
804 | /* '' */
805 | .icon-music:before {
806 | content: '\e802';
807 | }
808 |
809 | /* '' */
810 | .icon-search:before {
811 | content: '\e803';
812 | }
813 |
814 | /* '' */
815 | .icon-flashlight:before {
816 | content: '\e804';
817 | }
818 |
819 | /* '' */
820 | .icon-mail:before {
821 | content: '\e805';
822 | }
823 |
824 | /* '' */
825 | .icon-heart:before {
826 | content: '\e806';
827 | }
828 |
829 | /* '' */
830 | .icon-heart-empty:before {
831 | content: '\e807';
832 | }
833 |
834 | /* '' */
835 | .icon-star:before {
836 | content: '\e808';
837 | }
838 |
839 | /* '' */
840 | .icon-star-empty:before {
841 | content: '\e809';
842 | }
843 |
844 | /* '' */
845 | .icon-user:before {
846 | content: '\e80a';
847 | }
848 |
849 | /* '' */
850 | .icon-users:before {
851 | content: '\e80b';
852 | }
853 |
854 | /* '' */
855 | .icon-user-add:before {
856 | content: '\e80c';
857 | }
858 |
859 | /* '' */
860 | .icon-video:before {
861 | content: '\e80d';
862 | }
863 |
864 | /* '' */
865 | .icon-picture:before {
866 | content: '\e80e';
867 | }
868 |
869 | /* '' */
870 | .icon-camera:before {
871 | content: '\e80f';
872 | }
873 |
874 | /* '' */
875 | .icon-layout:before {
876 | content: '\e810';
877 | }
878 |
879 | /* '' */
880 | .icon-menu:before {
881 | content: '\e811';
882 | }
883 |
884 | /* '' */
885 | .icon-check:before {
886 | content: '\e812';
887 | }
888 |
889 | /* '' */
890 | .icon-cancel:before {
891 | content: '\e813';
892 | }
893 |
894 | /* '' */
895 | .icon-cancel-circled:before {
896 | content: '\e814';
897 | }
898 |
899 | /* '' */
900 | .icon-cancel-squared:before {
901 | content: '\e815';
902 | }
903 |
904 | /* '' */
905 | .icon-plus:before {
906 | content: '\e816';
907 | }
908 |
909 | /* '' */
910 | .icon-plus-circled:before {
911 | content: '\e817';
912 | }
913 |
914 | /* '' */
915 | .icon-plus-squared:before {
916 | content: '\e818';
917 | }
918 |
919 | /* '' */
920 | .icon-minus:before {
921 | content: '\e819';
922 | }
923 |
924 | /* '' */
925 | .icon-minus-circled:before {
926 | content: '\e81a';
927 | }
928 |
929 | /* '' */
930 | .icon-minus-squared:before {
931 | content: '\e81b';
932 | }
933 |
934 | /* '' */
935 | .icon-help:before {
936 | content: '\e81c';
937 | }
938 |
939 | /* '' */
940 | .icon-help-circled:before {
941 | content: '\e81d';
942 | }
943 |
944 | /* '' */
945 | .icon-info:before {
946 | content: '\e81e';
947 | }
948 |
949 | /* '' */
950 | .icon-info-circled:before {
951 | content: '\e81f';
952 | }
953 |
954 | /* '' */
955 | .icon-back:before {
956 | content: '\e820';
957 | }
958 |
959 | /* '' */
960 | .icon-home:before {
961 | content: '\e821';
962 | }
963 |
964 | /* '' */
965 | .icon-link:before {
966 | content: '\e822';
967 | }
968 |
969 | /* '' */
970 | .icon-attach:before {
971 | content: '\e823';
972 | }
973 |
974 | /* '' */
975 | .icon-lock:before {
976 | content: '\e824';
977 | }
978 |
979 | /* '' */
980 | .icon-lock-open:before {
981 | content: '\e825';
982 | }
983 |
984 | /* '' */
985 | .icon-eye:before {
986 | content: '\e826';
987 | }
988 |
989 | /* '' */
990 | .icon-tag:before {
991 | content: '\e827';
992 | }
993 |
994 | /* '' */
995 | .icon-bookmark:before {
996 | content: '\e828';
997 | }
998 |
999 | /* '' */
1000 | .icon-bookmarks:before {
1001 | content: '\e829';
1002 | }
1003 |
1004 | /* '' */
1005 | .icon-flag:before {
1006 | content: '\e82a';
1007 | }
1008 |
1009 | /* '' */
1010 | .icon-thumbs-up:before {
1011 | content: '\e82b';
1012 | }
1013 |
1014 | /* '' */
1015 | .icon-thumbs-down:before {
1016 | content: '\e82c';
1017 | }
1018 |
1019 | /* '' */
1020 | .icon-download:before {
1021 | content: '\e82d';
1022 | }
1023 |
1024 | /* '' */
1025 | .icon-upload:before {
1026 | content: '\e82e';
1027 | }
1028 |
1029 | /* '' */
1030 | .icon-upload-cloud:before {
1031 | content: '\e82f';
1032 | }
1033 |
1034 | /* '' */
1035 | .icon-reply:before {
1036 | content: '\e830';
1037 | }
1038 |
1039 | /* '' */
1040 | .icon-reply-all:before {
1041 | content: '\e831';
1042 | }
1043 |
1044 | /* '' */
1045 | .icon-forward:before {
1046 | content: '\e832';
1047 | }
1048 |
1049 | /* '' */
1050 | .icon-quote:before {
1051 | content: '\e833';
1052 | }
1053 |
1054 | /* '' */
1055 | .icon-code:before {
1056 | content: '\e834';
1057 | }
1058 |
1059 | /* '' */
1060 | .icon-export:before {
1061 | content: '\e835';
1062 | }
1063 |
1064 | /* '' */
1065 | .icon-pencil:before {
1066 | content: '\e836';
1067 | }
1068 |
1069 | /* '' */
1070 | .icon-feather:before {
1071 | content: '\e837';
1072 | }
1073 |
1074 | /* '' */
1075 | .icon-print:before {
1076 | content: '\e838';
1077 | }
1078 |
1079 | /* '' */
1080 | .icon-retweet:before {
1081 | content: '\e839';
1082 | }
1083 |
1084 | /* '' */
1085 | .icon-keyboard:before {
1086 | content: '\e83a';
1087 | }
1088 |
1089 | /* '' */
1090 | .icon-comment:before {
1091 | content: '\e83b';
1092 | }
1093 |
1094 | /* '' */
1095 | .icon-chat:before {
1096 | content: '\e83c';
1097 | }
1098 |
1099 | /* '' */
1100 | .icon-bell:before {
1101 | content: '\e83d';
1102 | }
1103 |
1104 | /* '' */
1105 | .icon-attention:before {
1106 | content: '\e83e';
1107 | }
1108 |
1109 | /* '' */
1110 | .icon-alert:before {
1111 | content: '\e83f';
1112 | }
1113 |
1114 | /* '' */
1115 | .icon-vcard:before {
1116 | content: '\e840';
1117 | }
1118 |
1119 | /* '' */
1120 | .icon-address:before {
1121 | content: '\e841';
1122 | }
1123 |
1124 | /* '' */
1125 | .icon-location:before {
1126 | content: '\e842';
1127 | }
1128 |
1129 | /* '' */
1130 | .icon-map:before {
1131 | content: '\e843';
1132 | }
1133 |
1134 | /* '' */
1135 | .icon-direction:before {
1136 | content: '\e844';
1137 | }
1138 |
1139 | /* '' */
1140 | .icon-compass:before {
1141 | content: '\e845';
1142 | }
1143 |
1144 | /* '' */
1145 | .icon-cup:before {
1146 | content: '\e846';
1147 | }
1148 |
1149 | /* '' */
1150 | .icon-trash:before {
1151 | content: '\e847';
1152 | }
1153 |
1154 | /* '' */
1155 | .icon-doc:before {
1156 | content: '\e848';
1157 | }
1158 |
1159 | /* '' */
1160 | .icon-docs:before {
1161 | content: '\e849';
1162 | }
1163 |
1164 | /* '' */
1165 | .icon-doc-landscape:before {
1166 | content: '\e84a';
1167 | }
1168 |
1169 | /* '' */
1170 | .icon-doc-text:before {
1171 | content: '\e84b';
1172 | }
1173 |
1174 | /* '' */
1175 | .icon-doc-text-inv:before {
1176 | content: '\e84c';
1177 | }
1178 |
1179 | /* '' */
1180 | .icon-newspaper:before {
1181 | content: '\e84d';
1182 | }
1183 |
1184 | /* '' */
1185 | .icon-book-open:before {
1186 | content: '\e84e';
1187 | }
1188 |
1189 | /* '' */
1190 | .icon-book:before {
1191 | content: '\e84f';
1192 | }
1193 |
1194 | /* '' */
1195 | .icon-folder:before {
1196 | content: '\e850';
1197 | }
1198 |
1199 | /* '' */
1200 | .icon-archive:before {
1201 | content: '\e851';
1202 | }
1203 |
1204 | /* '' */
1205 | .icon-box:before {
1206 | content: '\e852';
1207 | }
1208 |
1209 | /* '' */
1210 | .icon-rss:before {
1211 | content: '\e853';
1212 | }
1213 |
1214 | /* '' */
1215 | .icon-phone:before {
1216 | content: '\e854';
1217 | }
1218 |
1219 | /* '' */
1220 | .icon-cog:before {
1221 | content: '\e855';
1222 | }
1223 |
1224 | /* '' */
1225 | .icon-tools:before {
1226 | content: '\e856';
1227 | }
1228 |
1229 | /* '' */
1230 | .icon-share:before {
1231 | content: '\e857';
1232 | }
1233 |
1234 | /* '' */
1235 | .icon-shareable:before {
1236 | content: '\e858';
1237 | }
1238 |
1239 | /* '' */
1240 | .icon-basket:before {
1241 | content: '\e859';
1242 | }
1243 |
1244 | /* '' */
1245 | .icon-bag:before {
1246 | content: '\e85a';
1247 | }
1248 |
1249 | /* '' */
1250 | .icon-calendar:before {
1251 | content: '\e85b';
1252 | }
1253 |
1254 | /* '' */
1255 | .icon-login:before {
1256 | content: '\e85c';
1257 | }
1258 |
1259 | /* '' */
1260 | .icon-logout:before {
1261 | content: '\e85d';
1262 | }
1263 |
1264 | /* '' */
1265 | .icon-mic:before {
1266 | content: '\e85e';
1267 | }
1268 |
1269 | /* '' */
1270 | .icon-mute:before {
1271 | content: '\e85f';
1272 | }
1273 |
1274 | /* '' */
1275 | .icon-sound:before {
1276 | content: '\e860';
1277 | }
1278 |
1279 | /* '' */
1280 | .icon-volume:before {
1281 | content: '\e861';
1282 | }
1283 |
1284 | /* '' */
1285 | .icon-clock:before {
1286 | content: '\e862';
1287 | }
1288 |
1289 | /* '' */
1290 | .icon-hourglass:before {
1291 | content: '\e863';
1292 | }
1293 |
1294 | /* '' */
1295 | .icon-lamp:before {
1296 | content: '\e864';
1297 | }
1298 |
1299 | /* '' */
1300 | .icon-light-down:before {
1301 | content: '\e865';
1302 | }
1303 |
1304 | /* '' */
1305 | .icon-light-up:before {
1306 | content: '\e866';
1307 | }
1308 |
1309 | /* '' */
1310 | .icon-adjust:before {
1311 | content: '\e867';
1312 | }
1313 |
1314 | /* '' */
1315 | .icon-block:before {
1316 | content: '\e868';
1317 | }
1318 |
1319 | /* '' */
1320 | .icon-resize-full:before {
1321 | content: '\e869';
1322 | }
1323 |
1324 | /* '' */
1325 | .icon-resize-small:before {
1326 | content: '\e86a';
1327 | }
1328 |
1329 | /* '' */
1330 | .icon-popup:before {
1331 | content: '\e86b';
1332 | }
1333 |
1334 | /* '' */
1335 | .icon-publish:before {
1336 | content: '\e86c';
1337 | }
1338 |
1339 | /* '' */
1340 | .icon-window:before {
1341 | content: '\e86d';
1342 | }
1343 |
1344 | /* '' */
1345 | .icon-arrow-combo:before {
1346 | content: '\e86e';
1347 | }
1348 |
1349 | /* '' */
1350 | .icon-down-circled:before {
1351 | content: '\e86f';
1352 | }
1353 |
1354 | /* '' */
1355 | .icon-left-circled:before {
1356 | content: '\e870';
1357 | }
1358 |
1359 | /* '' */
1360 | .icon-right-circled:before {
1361 | content: '\e871';
1362 | }
1363 |
1364 | /* '' */
1365 | .icon-up-circled:before {
1366 | content: '\e872';
1367 | }
1368 |
1369 | /* '' */
1370 | .icon-down-open:before {
1371 | content: '\e873';
1372 | }
1373 |
1374 | /* '' */
1375 | .icon-left-open:before {
1376 | content: '\e874';
1377 | }
1378 |
1379 | /* '' */
1380 | .icon-right-open:before {
1381 | content: '\e875';
1382 | }
1383 |
1384 | /* '' */
1385 | .icon-up-open:before {
1386 | content: '\e876';
1387 | }
1388 |
1389 | /* '' */
1390 | .icon-down-open-mini:before {
1391 | content: '\e877';
1392 | }
1393 |
1394 | /* '' */
1395 | .icon-left-open-mini:before {
1396 | content: '\e878';
1397 | }
1398 |
1399 | /* '' */
1400 | .icon-right-open-mini:before {
1401 | content: '\e879';
1402 | }
1403 |
1404 | /* '' */
1405 | .icon-up-open-mini:before {
1406 | content: '\e87a';
1407 | }
1408 |
1409 | /* '' */
1410 | .icon-down-open-big:before {
1411 | content: '\e87b';
1412 | }
1413 |
1414 | /* '' */
1415 | .icon-left-open-big:before {
1416 | content: '\e87c';
1417 | }
1418 |
1419 | /* '' */
1420 | .icon-right-open-big:before {
1421 | content: '\e87d';
1422 | }
1423 |
1424 | /* '' */
1425 | .icon-up-open-big:before {
1426 | content: '\e87e';
1427 | }
1428 |
1429 | /* '' */
1430 | .icon-down:before {
1431 | content: '\e87f';
1432 | }
1433 |
1434 | /* '' */
1435 | .icon-left:before {
1436 | content: '\e880';
1437 | }
1438 |
1439 | /* '' */
1440 | .icon-right:before {
1441 | content: '\e881';
1442 | }
1443 |
1444 | /* '' */
1445 | .icon-up:before {
1446 | content: '\e882';
1447 | }
1448 |
1449 | /* '' */
1450 | .icon-down-dir:before {
1451 | content: '\e883';
1452 | }
1453 |
1454 | /* '' */
1455 | .icon-left-dir:before {
1456 | content: '\e884';
1457 | }
1458 |
1459 | /* '' */
1460 | .icon-right-dir:before {
1461 | content: '\e885';
1462 | }
1463 |
1464 | /* '' */
1465 | .icon-up-dir:before {
1466 | content: '\e886';
1467 | }
1468 |
1469 | /* '' */
1470 | .icon-down-bold:before {
1471 | content: '\e887';
1472 | }
1473 |
1474 | /* '' */
1475 | .icon-left-bold:before {
1476 | content: '\e888';
1477 | }
1478 |
1479 | /* '' */
1480 | .icon-right-bold:before {
1481 | content: '\e889';
1482 | }
1483 |
1484 | /* '' */
1485 | .icon-up-bold:before {
1486 | content: '\e88a';
1487 | }
1488 |
1489 | /* '' */
1490 | .icon-down-thin:before {
1491 | content: '\e88b';
1492 | }
1493 |
1494 | /* '' */
1495 | .icon-left-thin:before {
1496 | content: '\e88c';
1497 | }
1498 |
1499 | /* '' */
1500 | .icon-right-thin:before {
1501 | content: '\e88d';
1502 | }
1503 |
1504 | /* '' */
1505 | .icon-up-thin:before {
1506 | content: '\e88e';
1507 | }
1508 |
1509 | /* '' */
1510 | .icon-ccw:before {
1511 | content: '\e88f';
1512 | }
1513 |
1514 | /* '' */
1515 | .icon-cw:before {
1516 | content: '\e890';
1517 | }
1518 |
1519 | /* '' */
1520 | .icon-arrows-ccw:before {
1521 | content: '\e891';
1522 | }
1523 |
1524 | /* '' */
1525 | .icon-level-down:before {
1526 | content: '\e892';
1527 | }
1528 |
1529 | /* '' */
1530 | .icon-level-up:before {
1531 | content: '\e893';
1532 | }
1533 |
1534 | /* '' */
1535 | .icon-shuffle:before {
1536 | content: '\e894';
1537 | }
1538 |
1539 | /* '' */
1540 | .icon-loop:before {
1541 | content: '\e895';
1542 | }
1543 |
1544 | /* '' */
1545 | .icon-switch:before {
1546 | content: '\e896';
1547 | }
1548 |
1549 | /* '' */
1550 | .icon-play:before {
1551 | content: '\e897';
1552 | }
1553 |
1554 | /* '' */
1555 | .icon-stop:before {
1556 | content: '\e898';
1557 | }
1558 |
1559 | /* '' */
1560 | .icon-pause:before {
1561 | content: '\e899';
1562 | }
1563 |
1564 | /* '' */
1565 | .icon-record:before {
1566 | content: '\e89a';
1567 | }
1568 |
1569 | /* '' */
1570 | .icon-to-end:before {
1571 | content: '\e89b';
1572 | }
1573 |
1574 | /* '' */
1575 | .icon-to-start:before {
1576 | content: '\e89c';
1577 | }
1578 |
1579 | /* '' */
1580 | .icon-fast-forward:before {
1581 | content: '\e89d';
1582 | }
1583 |
1584 | /* '' */
1585 | .icon-fast-backward:before {
1586 | content: '\e89e';
1587 | }
1588 |
1589 | /* '' */
1590 | .icon-progress-0:before {
1591 | content: '\e89f';
1592 | }
1593 |
1594 | /* '' */
1595 | .icon-progress-1:before {
1596 | content: '\e8a0';
1597 | }
1598 |
1599 | /* '' */
1600 | .icon-progress-2:before {
1601 | content: '\e8a1';
1602 | }
1603 |
1604 | /* '' */
1605 | .icon-progress-3:before {
1606 | content: '\e8a2';
1607 | }
1608 |
1609 | /* '' */
1610 | .icon-target:before {
1611 | content: '\e8a3';
1612 | }
1613 |
1614 | /* '' */
1615 | .icon-palette:before {
1616 | content: '\e8a4';
1617 | }
1618 |
1619 | /* '' */
1620 | .icon-list:before {
1621 | content: '\e8a5';
1622 | }
1623 |
1624 | /* '' */
1625 | .icon-list-add:before {
1626 | content: '\e8a6';
1627 | }
1628 |
1629 | /* '' */
1630 | .icon-signal:before {
1631 | content: '\e8a7';
1632 | }
1633 |
1634 | /* '' */
1635 | .icon-trophy:before {
1636 | content: '\e8a8';
1637 | }
1638 |
1639 | /* '' */
1640 | .icon-battery:before {
1641 | content: '\e8a9';
1642 | }
1643 |
1644 | /* '' */
1645 | .icon-back-in-time:before {
1646 | content: '\e8aa';
1647 | }
1648 |
1649 | /* '' */
1650 | .icon-monitor:before {
1651 | content: '\e8ab';
1652 | }
1653 |
1654 | /* '' */
1655 | .icon-mobile:before {
1656 | content: '\e8ac';
1657 | }
1658 |
1659 | /* '' */
1660 | .icon-network:before {
1661 | content: '\e8ad';
1662 | }
1663 |
1664 | /* '' */
1665 | .icon-cd:before {
1666 | content: '\e8ae';
1667 | }
1668 |
1669 | /* '' */
1670 | .icon-inbox:before {
1671 | content: '\e8af';
1672 | }
1673 |
1674 | /* '' */
1675 | .icon-install:before {
1676 | content: '\e8b0';
1677 | }
1678 |
1679 | /* '' */
1680 | .icon-globe:before {
1681 | content: '\e8b1';
1682 | }
1683 |
1684 | /* '' */
1685 | .icon-cloud:before {
1686 | content: '\e8b2';
1687 | }
1688 |
1689 | /* '' */
1690 | .icon-cloud-thunder:before {
1691 | content: '\e8b3';
1692 | }
1693 |
1694 | /* '' */
1695 | .icon-flash:before {
1696 | content: '\e8b4';
1697 | }
1698 |
1699 | /* '' */
1700 | .icon-moon:before {
1701 | content: '\e8b5';
1702 | }
1703 |
1704 | /* '' */
1705 | .icon-flight:before {
1706 | content: '\e8b6';
1707 | }
1708 |
1709 | /* '' */
1710 | .icon-paper-plane:before {
1711 | content: '\e8b7';
1712 | }
1713 |
1714 | /* '' */
1715 | .icon-leaf:before {
1716 | content: '\e8b8';
1717 | }
1718 |
1719 | /* '' */
1720 | .icon-lifebuoy:before {
1721 | content: '\e8b9';
1722 | }
1723 |
1724 | /* '' */
1725 | .icon-mouse:before {
1726 | content: '\e8ba';
1727 | }
1728 |
1729 | /* '' */
1730 | .icon-briefcase:before {
1731 | content: '\e8bb';
1732 | }
1733 |
1734 | /* '' */
1735 | .icon-suitcase:before {
1736 | content: '\e8bc';
1737 | }
1738 |
1739 | /* '' */
1740 | .icon-dot:before {
1741 | content: '\e8bd';
1742 | }
1743 |
1744 | /* '' */
1745 | .icon-dot-2:before {
1746 | content: '\e8be';
1747 | }
1748 |
1749 | /* '' */
1750 | .icon-dot-3:before {
1751 | content: '\e8bf';
1752 | }
1753 |
1754 | /* '' */
1755 | .icon-brush:before {
1756 | content: '\e8c0';
1757 | }
1758 |
1759 | /* '' */
1760 | .icon-magnet:before {
1761 | content: '\e8c1';
1762 | }
1763 |
1764 | /* '' */
1765 | .icon-infinity:before {
1766 | content: '\e8c2';
1767 | }
1768 |
1769 | /* '' */
1770 | .icon-erase:before {
1771 | content: '\e8c3';
1772 | }
1773 |
1774 | /* '' */
1775 | .icon-chart-pie:before {
1776 | content: '\e8c4';
1777 | }
1778 |
1779 | /* '' */
1780 | .icon-chart-line:before {
1781 | content: '\e8c5';
1782 | }
1783 |
1784 | /* '' */
1785 | .icon-chart-bar:before {
1786 | content: '\e8c6';
1787 | }
1788 |
1789 | /* '' */
1790 | .icon-chart-area:before {
1791 | content: '\e8c7';
1792 | }
1793 |
1794 | /* '' */
1795 | .icon-tape:before {
1796 | content: '\e8c8';
1797 | }
1798 |
1799 | /* '' */
1800 | .icon-graduation-cap:before {
1801 | content: '\e8c9';
1802 | }
1803 |
1804 | /* '' */
1805 | .icon-language:before {
1806 | content: '\e8ca';
1807 | }
1808 |
1809 | /* '' */
1810 | .icon-ticket:before {
1811 | content: '\e8cb';
1812 | }
1813 |
1814 | /* '' */
1815 | .icon-water:before {
1816 | content: '\e8cc';
1817 | }
1818 |
1819 | /* '' */
1820 | .icon-droplet:before {
1821 | content: '\e8cd';
1822 | }
1823 |
1824 | /* '' */
1825 | .icon-air:before {
1826 | content: '\e8ce';
1827 | }
1828 |
1829 | /* '' */
1830 | .icon-credit-card:before {
1831 | content: '\e8cf';
1832 | }
1833 |
1834 | /* '' */
1835 | .icon-floppy:before {
1836 | content: '\e8d0';
1837 | }
1838 |
1839 | /* '' */
1840 | .icon-clipboard:before {
1841 | content: '\e8d1';
1842 | }
1843 |
1844 | /* '' */
1845 | .icon-megaphone:before {
1846 | content: '\e8d2';
1847 | }
1848 |
1849 | /* '' */
1850 | .icon-database:before {
1851 | content: '\e8d3';
1852 | }
1853 |
1854 | /* '' */
1855 | .icon-drive:before {
1856 | content: '\e8d4';
1857 | }
1858 |
1859 | /* '' */
1860 | .icon-bucket:before {
1861 | content: '\e8d5';
1862 | }
1863 |
1864 | /* '' */
1865 | .icon-thermometer:before {
1866 | content: '\e8d6';
1867 | }
1868 |
1869 | /* '' */
1870 | .icon-key:before {
1871 | content: '\e8d7';
1872 | }
1873 |
1874 | /* '' */
1875 | .icon-flow-cascade:before {
1876 | content: '\e8d8';
1877 | }
1878 |
1879 | /* '' */
1880 | .icon-flow-branch:before {
1881 | content: '\e8d9';
1882 | }
1883 |
1884 | /* '' */
1885 | .icon-flow-tree:before {
1886 | content: '\e8da';
1887 | }
1888 |
1889 | /* '' */
1890 | .icon-flow-line:before {
1891 | content: '\e8db';
1892 | }
1893 |
1894 | /* '' */
1895 | .icon-flow-parallel:before {
1896 | content: '\e8dc';
1897 | }
1898 |
1899 | /* '' */
1900 | .icon-rocket:before {
1901 | content: '\e8dd';
1902 | }
1903 |
1904 | /* '' */
1905 | .icon-gauge:before {
1906 | content: '\e8de';
1907 | }
1908 |
1909 | /* '' */
1910 | .icon-traffic-cone:before {
1911 | content: '\e8df';
1912 | }
1913 |
1914 | /* '' */
1915 | .icon-cc:before {
1916 | content: '\e8e0';
1917 | }
1918 |
1919 | /* '' */
1920 | .icon-cc-by:before {
1921 | content: '\e8e1';
1922 | }
1923 |
1924 | /* '' */
1925 | .icon-cc-nc:before {
1926 | content: '\e8e2';
1927 | }
1928 |
1929 | /* '' */
1930 | .icon-cc-nc-eu:before {
1931 | content: '\e8e3';
1932 | }
1933 |
1934 | /* '' */
1935 | .icon-cc-nc-jp:before {
1936 | content: '\e8e4';
1937 | }
1938 |
1939 | /* '' */
1940 | .icon-cc-sa:before {
1941 | content: '\e8e5';
1942 | }
1943 |
1944 | /* '' */
1945 | .icon-cc-nd:before {
1946 | content: '\e8e6';
1947 | }
1948 |
1949 | /* '' */
1950 | .icon-cc-pd:before {
1951 | content: '\e8e7';
1952 | }
1953 |
1954 | /* '' */
1955 | .icon-cc-zero:before {
1956 | content: '\e8e8';
1957 | }
1958 |
1959 | /* '' */
1960 | .icon-cc-share:before {
1961 | content: '\e8e9';
1962 | }
1963 |
1964 | /* '' */
1965 | .icon-cc-remix:before {
1966 | content: '\e8ea';
1967 | }
1968 |
1969 | /* '' */
1970 | .icon-github:before {
1971 | content: '\e8eb';
1972 | }
1973 |
1974 | /* '' */
1975 | .icon-github-circled:before {
1976 | content: '\e8ec';
1977 | }
1978 |
1979 | /* '' */
1980 | .icon-flickr:before {
1981 | content: '\e8ed';
1982 | }
1983 |
1984 | /* '' */
1985 | .icon-flickr-circled:before {
1986 | content: '\e8ee';
1987 | }
1988 |
1989 | /* '' */
1990 | .icon-vimeo:before {
1991 | content: '\e8ef';
1992 | }
1993 |
1994 | /* '' */
1995 | .icon-vimeo-circled:before {
1996 | content: '\e8f0';
1997 | }
1998 |
1999 | /* '' */
2000 | .icon-twitter:before {
2001 | content: '\e8f1';
2002 | }
2003 |
2004 | /* '' */
2005 | .icon-twitter-circled:before {
2006 | content: '\e8f2';
2007 | }
2008 |
2009 | /* '' */
2010 | .icon-facebook:before {
2011 | content: '\e8f3';
2012 | }
2013 |
2014 | /* '' */
2015 | .icon-facebook-circled:before {
2016 | content: '\e8f4';
2017 | }
2018 |
2019 | /* '' */
2020 | .icon-facebook-squared:before {
2021 | content: '\e8f5';
2022 | }
2023 |
2024 | /* '' */
2025 | .icon-gplus:before {
2026 | content: '\e8f6';
2027 | }
2028 |
2029 | /* '' */
2030 | .icon-gplus-circled:before {
2031 | content: '\e8f7';
2032 | }
2033 |
2034 | /* '' */
2035 | .icon-pinterest:before {
2036 | content: '\e8f8';
2037 | }
2038 |
2039 | /* '' */
2040 | .icon-pinterest-circled:before {
2041 | content: '\e8f9';
2042 | }
2043 |
2044 | /* '' */
2045 | .icon-tumblr:before {
2046 | content: '\e8fa';
2047 | }
2048 |
2049 | /* '' */
2050 | .icon-tumblr-circled:before {
2051 | content: '\e8fb';
2052 | }
2053 |
2054 | /* '' */
2055 | .icon-linkedin:before {
2056 | content: '\e8fc';
2057 | }
2058 |
2059 | /* '' */
2060 | .icon-linkedin-circled:before {
2061 | content: '\e8fd';
2062 | }
2063 |
2064 | /* '' */
2065 | .icon-dribbble:before {
2066 | content: '\e8fe';
2067 | }
2068 |
2069 | /* '' */
2070 | .icon-dribbble-circled:before {
2071 | content: '\e8ff';
2072 | }
2073 |
2074 | /* '' */
2075 | .icon-stumbleupon:before {
2076 | content: '\e900';
2077 | }
2078 |
2079 | /* '' */
2080 | .icon-stumbleupon-circled:before {
2081 | content: '\e901';
2082 | }
2083 |
2084 | /* '' */
2085 | .icon-lastfm:before {
2086 | content: '\e902';
2087 | }
2088 |
2089 | /* '' */
2090 | .icon-lastfm-circled:before {
2091 | content: '\e903';
2092 | }
2093 |
2094 | /* '' */
2095 | .icon-rdio:before {
2096 | content: '\e904';
2097 | }
2098 |
2099 | /* '' */
2100 | .icon-rdio-circled:before {
2101 | content: '\e905';
2102 | }
2103 |
2104 | /* '' */
2105 | .icon-spotify:before {
2106 | content: '\e906';
2107 | }
2108 |
2109 | /* '' */
2110 | .icon-spotify-circled:before {
2111 | content: '\e907';
2112 | }
2113 |
2114 | /* '' */
2115 | .icon-qq:before {
2116 | content: '\e908';
2117 | }
2118 |
2119 | /* '' */
2120 | .icon-instagram:before {
2121 | content: '\e909';
2122 | }
2123 |
2124 | /* '' */
2125 | .icon-dropbox:before {
2126 | content: '\e90a';
2127 | }
2128 |
2129 | /* '' */
2130 | .icon-evernote:before {
2131 | content: '\e90b';
2132 | }
2133 |
2134 | /* '' */
2135 | .icon-flattr:before {
2136 | content: '\e90c';
2137 | }
2138 |
2139 | /* '' */
2140 | .icon-skype:before {
2141 | content: '\e90d';
2142 | }
2143 |
2144 | /* '' */
2145 | .icon-skype-circled:before {
2146 | content: '\e90e';
2147 | }
2148 |
2149 | /* '' */
2150 | .icon-renren:before {
2151 | content: '\e90f';
2152 | }
2153 |
2154 | /* '' */
2155 | .icon-sina-weibo:before {
2156 | content: '\e910';
2157 | }
2158 |
2159 | /* '' */
2160 | .icon-paypal:before {
2161 | content: '\e911';
2162 | }
2163 |
2164 | /* '' */
2165 | .icon-picasa:before {
2166 | content: '\e912';
2167 | }
2168 |
2169 | /* '' */
2170 | .icon-soundcloud:before {
2171 | content: '\e913';
2172 | }
2173 |
2174 | /* '' */
2175 | .icon-mixi:before {
2176 | content: '\e914';
2177 | }
2178 |
2179 | /* '' */
2180 | .icon-behance:before {
2181 | content: '\e915';
2182 | }
2183 |
2184 | /* '' */
2185 | .icon-google-circles:before {
2186 | content: '\e916';
2187 | }
2188 |
2189 | /* '' */
2190 | .icon-vkontakte:before {
2191 | content: '\e917';
2192 | }
2193 |
2194 | /* '' */
2195 | .icon-smashing:before {
2196 | content: '\e918';
2197 | }
2198 |
2199 | /* '' */
2200 | .icon-sweden:before {
2201 | content: '\e919';
2202 | }
2203 |
2204 | /* '' */
2205 | .icon-db-shape:before {
2206 | content: '\e91a';
2207 | }
2208 |
2209 | /* '' */
2210 | .icon-logo-db:before {
2211 | content: '\e91b';
2212 | }
2213 |
2214 | /* '' */
2215 | table {
2216 | width: 100%;
2217 | border: 0;
2218 | border-collapse: separate;
2219 | font-size: 12px;
2220 | text-align: left;
2221 | }
2222 |
2223 | thead {
2224 | background-color: #f5f5f4;
2225 | }
2226 |
2227 | tbody {
2228 | background-color: #fff;
2229 | }
2230 |
2231 | .table-striped tr:nth-child(even) {
2232 | background-color: #f5f5f4;
2233 | }
2234 |
2235 | tr:active,
2236 | .table-striped tr:active:nth-child(even) {
2237 | color: #fff;
2238 | background-color: #116cd6;
2239 | }
2240 |
2241 | thead tr:active {
2242 | color: #333;
2243 | background-color: #f5f5f4;
2244 | }
2245 |
2246 | th {
2247 | font-weight: normal;
2248 | border-right: 1px solid #ddd;
2249 | border-bottom: 1px solid #ddd;
2250 | }
2251 |
2252 | th,
2253 | td {
2254 | padding: 2px 15px;
2255 | white-space: nowrap;
2256 | overflow: hidden;
2257 | text-overflow: ellipsis;
2258 | }
2259 | th:last-child,
2260 | td:last-child {
2261 | border-right: 0;
2262 | }
2263 |
2264 | .tab-group {
2265 | margin-top: -1px;
2266 | display: flex;
2267 | border-top: 1px solid #989698;
2268 | border-bottom: 1px solid #989698;
2269 | }
2270 |
2271 | .tab-item {
2272 | position: relative;
2273 | flex: 1;
2274 | padding: 3px;
2275 | font-size: 12px;
2276 | text-align: center;
2277 | border-left: 1px solid #989698;
2278 | background-color: #b8b6b8;
2279 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #b8b6b8), color-stop(100%, #b0aeb0));
2280 | background-image: -webkit-linear-gradient(top, #b8b6b8 0%, #b0aeb0 100%);
2281 | background-image: linear-gradient(to bottom, #b8b6b8 0%, #b0aeb0 100%);
2282 | }
2283 | .tab-item:first-child {
2284 | border-left: 0;
2285 | }
2286 | .tab-item.active {
2287 | background-color: #d4d2d4;
2288 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d4d2d4), color-stop(100%, #cccacc));
2289 | background-image: -webkit-linear-gradient(top, #d4d2d4 0%, #cccacc 100%);
2290 | background-image: linear-gradient(to bottom, #d4d2d4 0%, #cccacc 100%);
2291 | }
2292 | .tab-item .icon-close-tab {
2293 | position: absolute;
2294 | top: 50%;
2295 | left: 5px;
2296 | width: 15px;
2297 | height: 15px;
2298 | font-size: 15px;
2299 | line-height: 15px;
2300 | text-align: center;
2301 | color: #666;
2302 | opacity: 0;
2303 | transition: opacity .1s linear, background-color .1s linear;
2304 | border-radius: 3px;
2305 | transform: translateY(-50%);
2306 | z-index: 10;
2307 | }
2308 | .tab-item:after {
2309 | position: absolute;
2310 | top: 0;
2311 | right: 0;
2312 | bottom: 0;
2313 | left: 0;
2314 | content: "";
2315 | background-color: rgba(0, 0, 0, 0.08);
2316 | opacity: 0;
2317 | transition: opacity .1s linear;
2318 | z-index: 1;
2319 | }
2320 | .tab-item:hover:not(.active):after {
2321 | opacity: 1;
2322 | }
2323 | .tab-item:hover .icon-close-tab {
2324 | opacity: 1;
2325 | }
2326 | .tab-item .icon-close-tab:hover {
2327 | background-color: rgba(0, 0, 0, 0.08);
2328 | }
2329 |
2330 | .tab-item-fixed {
2331 | flex: none;
2332 | padding: 3px 10px;
2333 | }
2334 |
--------------------------------------------------------------------------------
/app/photon/fonts/photon-entypo.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aesqe/electron-image-viewer/e856f4d28e09979c85bcf5840b0a938bd26e6fb9/app/photon/fonts/photon-entypo.eot
--------------------------------------------------------------------------------
/app/photon/fonts/photon-entypo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/photon/fonts/photon-entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aesqe/electron-image-viewer/e856f4d28e09979c85bcf5840b0a938bd26e6fb9/app/photon/fonts/photon-entypo.ttf
--------------------------------------------------------------------------------
/app/photon/fonts/photon-entypo.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aesqe/electron-image-viewer/e856f4d28e09979c85bcf5840b0a938bd26e6fb9/app/photon/fonts/photon-entypo.woff
--------------------------------------------------------------------------------
/app/style.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | margin: 0;
3 | }
4 |
5 | [disabled] {
6 | opacity: 0.75;
7 | pointer-events: none;
8 | }
9 |
10 | .window {
11 | background-color: #fff;
12 | transition: background-color 0.2s;
13 | box-shadow: inset 0 0 2px rgba(125, 74, 74, 0.22)
14 | }
15 |
16 | .maximized {
17 | background-color: #000;
18 | }
19 |
20 | .window::after {
21 | content: "";
22 | width: 100%;
23 | height: 100%;
24 | position: absolute;
25 | top: 0;
26 | left: 0;
27 | background-color: transparent;
28 | transition: background-color 0.25s;
29 | }
30 |
31 | .dragover::after {
32 | z-index: 10;
33 | background-color: rgba(211, 211, 211, 0.85);
34 | }
35 |
36 | #display {
37 | width: 100vw;
38 | height: calc(100vh - 35px);
39 | margin-top: 35px;
40 | background-repeat: no-repeat;
41 | background-size: contain;
42 | background-position: center;
43 | }
44 |
45 | .maximized #display {
46 | height: 100vh;
47 | margin-top: 0;
48 | }
49 |
50 | header {
51 | position: fixed;
52 | z-index: 2;
53 | width: 100%;
54 | top: 0;
55 | }
56 |
57 | .maximized header {
58 | display: none;
59 | -webkit-drag: none;
60 | }
61 |
62 | #current-of-display {
63 | min-width: 100px;
64 | box-shadow: none;
65 | }
66 |
67 | #drag-drop {
68 | display: flex;
69 | align-items: center;
70 | text-align: center;
71 | width: 100%;
72 | }
73 |
74 | #drag-drop p {
75 | width: 100%;
76 | color: darkgray;
77 | transition: color 0.25s;
78 | }
79 |
80 | .dragover #drag-drop p {
81 | color: black;
82 | }
83 |
84 | .color-picker {
85 | position: absolute;
86 | left: 0;
87 | top: 0;
88 | z-index: -1;
89 | width: 100%;
90 | height: 100%;
91 | opacity: 0;
92 | transition: opacity 0.2s;
93 | }
94 |
95 | .color-picker-visible .color-picker {
96 | z-index: 3;
97 | opacity: 1;
98 | }
99 |
100 | .color-picker input {
101 | width: 100px;
102 | height: 100px;
103 | position: absolute;
104 | left: calc(50% - 50px);
105 | top: calc(50% - 50px);
106 | padding: 3px 5px;
107 | }
108 |
109 | .filename {
110 | color: #00FF00;
111 | padding: 2px 5px;
112 | }
113 |
--------------------------------------------------------------------------------
/app/template.html:
--------------------------------------------------------------------------------
1 |
7 |
8 | {{#if files.length}}
9 |
32 | {{/if}}
33 |
34 |
35 | {{#if files.length}}
36 |
40 | {{#if displayFileName}}
41 |
42 | {{currentImage}}
43 |
44 | {{/if}}
45 |
46 | {{else}}
47 |
48 |
49 | Drag and drop a file or folder onto this window to start
50 |
51 |
52 | {{/if}}
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/build/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aesqe/electron-image-viewer/e856f4d28e09979c85bcf5840b0a938bd26e6fb9/build/background.png
--------------------------------------------------------------------------------
/build/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aesqe/electron-image-viewer/e856f4d28e09979c85bcf5840b0a938bd26e6fb9/build/icon.icns
--------------------------------------------------------------------------------
/build/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aesqe/electron-image-viewer/e856f4d28e09979c85bcf5840b0a938bd26e6fb9/build/icon.ico
--------------------------------------------------------------------------------
/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aesqe/electron-image-viewer/e856f4d28e09979c85bcf5840b0a938bd26e6fb9/images/icon.png
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | const { app, BrowserWindow } = require("electron");
2 | const { createMainWindow } = require("./window.js");
3 |
4 | let mainWindow = null;
5 |
6 | app.on("window-all-closed", function () {
7 | if (process.platform !== "darwin") {
8 | app.quit();
9 | }
10 | });
11 |
12 | app.on("activate-with-no-open-windows", function () {
13 | if (!mainWindow) {
14 | mainWindow = createMainWindow();
15 | }
16 | });
17 |
18 | app.on("ready", function () {
19 | mainWindow = createMainWindow();
20 |
21 | if (process.env.NODE_ENV === "development") {
22 | mainWindow.openDevTools();
23 | }
24 | });
25 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "electron-image-viewer",
3 | "productName": "electron-image-viewer",
4 | "version": "0.3.0",
5 | "description": "Image viewer",
6 | "main": "main.js",
7 | "author": "aesqe",
8 | "license": "ISC",
9 | "scripts": {
10 | "genver": "genversion app/js/lib/version.js",
11 | "start": "cross-env NODE_ENV=production electron .",
12 | "dev": "npm run genver && cross-env NODE_ENV=development electron .",
13 | "pack": "npm run genver && electron-builder --dir",
14 | "dist": "npm run genver && electron-builder",
15 | "postinstall": "electron-builder install-app-deps"
16 | },
17 | "dependencies": {
18 | "electron-store": "1.3.0",
19 | "fs-jetpack": "1.3.0",
20 | "hamsterjs": "1.1.2",
21 | "mousetrap": "1.6.0",
22 | "ractive": "^0.9.13",
23 | "ractive-events-tap": "0.3.1",
24 | "trash": "4.2.1"
25 | },
26 | "devDependencies": {
27 | "cross-env": "5.1.3",
28 | "electron": "1.8.2",
29 | "electron-builder": "20.2.0",
30 | "electron-packager": "11.0.1",
31 | "genversion": "2.0.1"
32 | },
33 | "build": {
34 | "appId": "electronImageViewer",
35 | "directories": {
36 | "output": "dist"
37 | },
38 | "mac": {
39 | "target": [
40 | "zip"
41 | ],
42 | "category": "public.app-category.utilities"
43 | },
44 | "win": {
45 | "target": [
46 | "nsis",
47 | "zip"
48 | ]
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/window.js:
--------------------------------------------------------------------------------
1 | const { app, BrowserWindow } = require("electron");
2 | const ElectronStore = require("electron-store");
3 | const { ipcMain } = require("electron");
4 |
5 | module.exports = {
6 | createMainWindow() {
7 | const store = new ElectronStore();
8 |
9 | let lastWindowState = store.get("lastWindowState");
10 |
11 | if (!lastWindowState) {
12 | lastWindowState = {
13 | x: 0,
14 | y: 0,
15 | width: 800,
16 | height: 600,
17 | maximized: false,
18 | };
19 |
20 | store.set("lastWindowState", lastWindowState);
21 | }
22 |
23 | let win = new BrowserWindow({
24 | title: "Electron image viewer",
25 | icon: "images/icon.png",
26 | position: "center",
27 | x: lastWindowState.x,
28 | y: lastWindowState.y,
29 | width: lastWindowState.width,
30 | height: lastWindowState.height,
31 | overlayScrollbars: true,
32 | resizable: true,
33 | toolbar: true,
34 | transparent: false,
35 | fullscreen: false,
36 | frame: false,
37 | show: false,
38 | });
39 |
40 | win.setMenu(null);
41 |
42 | if (lastWindowState.maximized) {
43 | win.maximize();
44 | }
45 |
46 | win.on("close", () => {
47 | const maximized = win.isMaximized();
48 |
49 | // avoid setting width and height to screen w/h values
50 | win.unmaximize();
51 |
52 | const bounds = win.getBounds();
53 | const { x, y, width, height } = bounds;
54 | const windowState = {
55 | maximized,
56 | width,
57 | height,
58 | x,
59 | y,
60 | };
61 |
62 | store.set("lastWindowState", windowState);
63 | });
64 |
65 | win.on("unresponsive", (e) => console.log(e));
66 | win.webContents.on("crashed", (e) => console.log(e));
67 | process.on("uncaughtException", (e) => console.log(e));
68 |
69 | win.webContents.on("did-finish-load", () => win.show());
70 |
71 | win.on("maximize", () => win.webContents.send("maximize"));
72 | win.on("unmaximize", () => win.webContents.send("unmaximize"));
73 |
74 | ipcMain.on("maximize", () => win.maximize());
75 | ipcMain.on("unmaximize", () => win.unmaximize());
76 |
77 | win.on("closed", () => setTimeout(() => (win = null), 250));
78 | ipcMain.on("quit", () => {
79 | win.closeDevTools();
80 | app.quit();
81 | });
82 |
83 | win.loadURL("file://" + __dirname + "/app/index.html");
84 |
85 | return win;
86 | }
87 | };
88 |
--------------------------------------------------------------------------------