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 |
