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