0
|
1 local Luan = require "luan:Luan.luan"
|
|
2 local error = Luan.error
|
|
3 local ipairs = Luan.ipairs or error()
|
|
4 local Table = require "luan:Table.luan"
|
|
5 local concat = Table.concat or error()
|
|
6 local Parsers = require "luan:Parsers.luan"
|
|
7 local json_string = Parsers.json_string or error()
|
|
8 local Io = require "luan:Io.luan"
|
|
9 local Http = require "luan:http/Http.luan"
|
|
10 local Shared = require "site:/lib/Shared.luan"
|
|
11 local head = Shared.head or error()
|
|
12 local body_header = Shared.body_header or error()
|
|
13 local footer = Shared.footer or error()
|
|
14 local get_hashtags_list = Shared.get_hashtags_list or error()
|
|
15 local User = require "site:/lib/User.luan"
|
|
16 local Pic = require "site:/lib/Pic.luan"
|
|
17 local get_user_pics = Pic.get_user_pics or error()
|
|
18
|
|
19
|
|
20 return function()
|
|
21 local user = User.current_required()
|
|
22 if user==nil then return end
|
|
23 local pics = get_user_pics(user.id)
|
|
24 local hashtags_list, hashtags_set = get_hashtags_list(pics)
|
|
25 Io.stdout = Http.response.text_writer()
|
|
26 %>
|
|
27 <!doctype html>
|
|
28 <html lang="en">
|
|
29 <head>
|
|
30 <% head() %>
|
|
31 <title>Link My Style</title>
|
|
32 <style>
|
|
33 div[pics_body] {
|
|
34 width: 90%;
|
|
35 margin-left: auto;
|
|
36 margin-right: auto;
|
|
37 }
|
|
38 div[pics] > span {
|
|
39 position: relative;
|
|
40 }
|
|
41 div[pics] span > img {
|
|
42 position: absolute;
|
|
43 height: 25%;
|
|
44 top: 0;
|
|
45 left: 0;
|
|
46 background-color: white;
|
|
47 border: 1px solid lightgrey;
|
|
48 opacity: 0.3;
|
|
49 padding: 4px;
|
|
50 touch-action: none;
|
|
51 }
|
|
52 div[is_hidden] {
|
|
53 position: absolute;
|
|
54 top: 50%;
|
|
55 left: 50%;
|
|
56 transform: translate(-50%,-50%);
|
|
57 color: white;
|
|
58 background-color: black;
|
|
59 opacity: 0.5;
|
|
60 padding: 20px;
|
|
61 }
|
|
62 div[add] {
|
|
63 margin-top: 20px;
|
|
64 margin-bottom: 40px;
|
|
65 margin-left: auto;
|
|
66 margin-right: auto;
|
|
67 max-width: 600px;
|
|
68 }
|
|
69 div[add] > * {
|
|
70 margin-bottom: 8px;
|
|
71 }
|
|
72 button[big] {
|
|
73 margin-top: 5px;
|
|
74 }
|
|
75 div[hashtags] {
|
|
76 text-align: center;
|
|
77 margin-bottom: 20px;
|
|
78 }
|
|
79 </style>
|
|
80 <style hashtag></style>
|
|
81 <script>
|
|
82 'use strict';
|
|
83
|
|
84 function addPic(uuid,filename) {
|
|
85 let title = document.querySelector('input[name="title"]');
|
|
86 let visible = document.querySelector('input[name="visible"]');
|
|
87 let data = 'uuid=' + uuid + '&filename=' + encodeURIComponent(filename) + '&title=' + encodeURIComponent(title.value)
|
|
88 if( visible.checked )
|
|
89 data += '&visible=on';
|
|
90 ajax( '/add_pic.js', data );
|
|
91 }
|
|
92
|
|
93 function startAddPic() {
|
|
94 let title = document.querySelector('input[name="title"]');
|
|
95 if( !title.reportValidity() )
|
|
96 return;
|
|
97 uploadcare.cropprOptions = {};
|
|
98 uploadcare.upload(addPic);
|
|
99 }
|
|
100
|
|
101 dad.onDropped = function(event) {
|
|
102 let dragging = event.original;
|
|
103 if( iDragging === indexOf(dragging.parentNode.querySelectorAll(dropSelector),dragging) )
|
|
104 return;
|
|
105 let picId = dragging.getAttribute('pic');
|
|
106 let prev = dragging.previousElementSibling;
|
|
107 let prevId = prev && prev.getAttribute('pic');
|
|
108 ajax( '/move_pic.js?pic='+picId+'&prev='+prevId );
|
|
109 };
|
|
110
|
|
111 dad.whatToDrag = function(draggable) {
|
|
112 return draggable.parentNode;
|
|
113 };
|
|
114
|
|
115 function dragInit() {
|
|
116 dropSelector = 'span';
|
|
117 let items = document.querySelectorAll('div[pics] span > img');
|
|
118 for( let i=0; i<items.length; i++ ) {
|
|
119 let item = items[i];
|
|
120 dad.setDraggable(item);
|
|
121 dad.setDropzone(item.parentNode);
|
|
122 }
|
|
123 }
|
|
124
|
|
125 let hashtags = <%=json_string(hashtags_set)%>;
|
|
126
|
|
127 function selectHashtag(hashtag) {
|
|
128 let style = document.querySelector('style[hashtag]');
|
|
129 if( hashtags[hashtag] ) {
|
|
130 style.innerHTML = `
|
|
131 div[pics] > span {
|
|
132 display: none;
|
|
133 }
|
|
134 div[pics] > span.${hashtag} {
|
|
135 display: block;
|
|
136 }
|
|
137 ` ;
|
|
138 history.replaceState(null,null,`#${hashtag}`);
|
|
139 } else {
|
|
140 style.innerHTML = '';
|
|
141 history.replaceState(null,null,'pics.html');
|
|
142 }
|
|
143 }
|
|
144
|
|
145 function init() {
|
|
146 dragInit();
|
|
147 let hash = location.hash;
|
|
148 if( hash ) {
|
|
149 hash = hash.slice(1); // remove '#'
|
|
150 if( hashtags[hash] ) {
|
|
151 let select = document.querySelector('[hashtags] select');
|
|
152 select.value = hash;
|
|
153 selectHashtag(hash);
|
|
154 }
|
|
155 }
|
|
156 }
|
|
157 </script>
|
|
158 </head>
|
|
159 <body>
|
|
160 <div full>
|
|
161 <% body_header() %>
|
|
162 <p top>Upload a photo. Once your photo has been saved, you can add links that are associated with it. Links can be outfits, products, affiliate links, the original image/video, or anything you like. Drag-and-drop the icon on the upper-left to change the order. The order on this page will also appear on your page.</p>
|
|
163 <div pics_body>
|
|
164 <div add>
|
|
165 <input type=text required name=title placeholder="Photo title">
|
|
166 <label clickable><input type=checkbox name=visible checked> Visible</label>
|
|
167 <button type=button big onclick="startAddPic()">Add an image</button>
|
|
168 </div>
|
|
169 <% if #hashtags_list > 0 then %>
|
|
170 <div hashtags>
|
|
171 <span select>
|
|
172 <select onchange="selectHashtag(value)">
|
|
173 <option value="">All Photos</option>
|
|
174 <% for _, hashtag in ipairs(hashtags_list) do %>
|
|
175 <option value="<%=hashtag%>">#<%=hashtag%></option>
|
|
176 <% end %>
|
|
177 </select>
|
|
178 </span>
|
|
179 </div>
|
|
180 <% end %>
|
|
181 <div pics>
|
|
182 <% for _, pic in ipairs(pics) do
|
|
183 local pic_id = pic.id
|
|
184 %>
|
|
185 <span pic="<%=pic_id%>" id="p-<%=pic_id%>" <%= pic.class or "" %> >
|
|
186 <a <%=pic.title_attr()%> href="/links.html?pic=<%=pic_id%>" draggable=false>
|
|
187 <img loading=lazy src="<%=pic.get_thumb_url()%>" draggable=false>
|
|
188 <% if pic.is_hidden then %>
|
|
189 <div is_hidden>Hidden</div>
|
|
190 <% end %>
|
|
191 </a>
|
|
192 <img src="/images/drag_indicator.svg">
|
|
193 </span>
|
|
194 <% end %>
|
|
195 </div>
|
|
196 </div>
|
|
197 <% footer() %>
|
|
198 </div>
|
|
199 <script> init(); </script>
|
|
200 </body>
|
|
201 </html>
|
|
202 <%
|
|
203 end
|