Mercurial Hosting > linkmystyle
comparison src/pics.html.luan @ 0:8f4df159f06b
start public repo
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 11 Jul 2025 20:57:49 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:8f4df159f06b |
---|---|
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 |