Mercurial Hosting > linkmystyle
view src/links.html.luan @ 3:b016e4b7c8da default tip
add read_me
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sat, 12 Jul 2025 12:51:36 -0600 |
parents | 8f4df159f06b |
children |
line wrap: on
line source
local Luan = require "luan:Luan.luan" local error = Luan.error local ipairs = Luan.ipairs or error() local Html = require "luan:Html.luan" local html_encode = Html.encode or error() local Table = require "luan:Table.luan" local concat = Table.concat or error() local Io = require "luan:Io.luan" local Http = require "luan:http/Http.luan" local Shared = require "site:/lib/Shared.luan" local head = Shared.head or error() local body_header = Shared.body_header or error() local footer = Shared.footer or error() local show_editable_link = Shared.show_editable_link or error() local User = require "site:/lib/User.luan" local Link = require "site:/lib/Link.luan" local get_owner_links = Link.get_owner_links or error() local Pic = require "site:/lib/Pic.luan" local Utils = require "site:/lib/Utils.luan" local to_list = Utils.to_list or error() local Logging = require "luan:logging/Logging.luan" local logger = Logging.logger "links.html" local function hashtags(pic) local hashtags = to_list(pic.hashtags) for i, hashtag in ipairs(hashtags) do hashtags[i] = "#"..hashtag end return concat(hashtags," ") end local function div_links(links,pic_id) %> <div links> <form add onsubmit="ajaxForm('add_link.js',this)" action="javascript:"> <% if pic_id ~= nil then %> <input type=hidden name=pic value="<%=pic_id%>"> <% end %> <input type=text required name=title placeholder="Title"> <input type=url required name=url placeholder="URL"> <button type=submit big>Add link</button> </form> <div start></div> <% for _, link in ipairs(links) do show_editable_link(link) end %> </div> <% end return function() local user = User.current_required() if user==nil then return end local owner = user local pic = Http.request.parameters.pic if pic ~= nil then pic = Pic.get_by_id(pic) if pic == nil then logger.warn("pic not found\n"..Http.request.raw_head) Http.response.send_error(404) return end pic.user_id == user.id or error() owner = pic end local links = get_owner_links(owner.id) local pic_id = pic and pic.id Io.stdout = Http.response.text_writer() %> <!doctype html> <html lang="en"> <head> <% head() %> <title>Link My Style</title> <style> form[add] { margin-bottom: 40px; } input { margin-bottom: 5px; } input[type="url"], input[type="text"] { display: block; } div[link] { margin-bottom: 20px; } button[small] { font-size: 12px; } div[delete2] p { margin-bottom: 5px; } div[link] > div:first-of-type { border-radius: 12px / 50%; margin-bottom: 5px; overflow: hidden; position: relative; border: 1px solid #ebebeb; } div[link] a { border-radius: initial; margin-bottom: initial; } div[link] a:hover { background-color: #243F47; } div[link] img { position: absolute; top: 0; height: 100%; background-color: white; opacity: 0.3; padding: 4px; touch-action: none; } <% if pic == nil then %> div[links] { margin-top: 20px; } <% else %> div[msg] { margin-top: 20px; margin-left: 5%; color: darkgreen; <% if Http.request.parameters.saved == nil then %> display: none; <% end %> } div[body] { margin-top: 40px; margin-bottom: 20px; } div[pic] img { width: 100%; display: block; margin-bottom: 5px; } div[pic] form { margin-top: 20px; } div[field] { margin-top: 1px; margin-bottom: 10px; } div[hashtags] { margin-top: 20px; } @media (min-width: 888px) { div[body] { display: flex; } div[pic] { width: 45%; margin-left: 5%; } div[outer_links] { width: 55%; margin-left: 5%; margin-right: 5%; } } @media (max-width: 887px) { div[pic] { display: block; width: 90%; margin-left: auto; margin-right: auto; margin-bottom: 40px; } } <% end %> </style> <script> 'use strict'; function clearAddForm() { let form = document.querySelector('form[add]'); form.querySelector('[name="title"]').value = ''; form.querySelector('[name="url"]').value = ''; } function deleteLink1(button,linkId) { let div = button.parentNode; if( div.querySelector('div[delete2]') ) return; let html = ` <div delete2> <p>Are you sure that you want to delete this?</p> <button delete2 small onclick="deleteLink2('${linkId}')">Yes</button> <button small onclick="undelete1(this)">No</button> </div> ` ; div.insertAdjacentHTML( 'beforeEnd', html ); div.scrollIntoViewIfNeeded(false); } function undelete1(button) { button.parentNode.outerHTML = ''; } function deleteLink2(linkId) { ajax( '/delete_link.js?link='+linkId ); } function deletePic1(button) { let div = button.parentNode; if( div.querySelector('div[delete2]') ) return; let html = ` <div delete2> <p>Are you sure that you want to delete this?</p> <button delete2 small onclick="deletePic2('<%=pic_id%>')">Yes</button> <button small onclick="undelete1(this)">No</button> </div> ` ; div.insertAdjacentHTML( 'beforeEnd', html ); div.scrollIntoViewIfNeeded(false); } function deletePic2() { ajax( '/delete_pic.js?pic=<%=pic_id%>' ); } function editLink(linkId) { ajax( '/edit_link.js?link='+linkId ); } function cancel(linkId) { ajax( '/cancel_edit_link.js?link='+linkId ); } dad.onDropped = function(event) { let dragging = event.original; if( iDragging === indexOf(dragging.parentNode.querySelectorAll(dropSelector),dragging) ) return; let linkId = dragging.getAttribute('link'); let prev = dragging.previousElementSibling; let prevId = prev && prev.getAttribute('link'); ajax( '/move_link.js?link='+linkId+'&prev='+prevId ); }; dad.whatToDrag = function(draggable) { return draggable.parentNode.parentNode; }; function dragInit() { dropSelector = 'div[link]'; let items = document.querySelectorAll('div[link] img'); for( let i=0; i<items.length; i++ ) { let item = items[i]; dad.setDraggable(item); dad.setDropzone(item.parentNode.parentNode); } } <% if pic ~= nil then %> function changePic(uuid,filename) { ajax( '/change_pic.js', 'pic=<%=pic.id%>&uuid=' + uuid + '&filename=' + encodeURIComponent(filename) ); } function startChangePic() { uploadcare.cropprOptions = {}; uploadcare.upload(changePic); } <% end %> </script> </head> <body> <div full> <% body_header() if pic == nil then %> <p top>Enter your title and a URL to create a link. Once saved, you can drag-and-drop the icon on the left to change the order. The order on this page will also appear on your page.</p> <% div_links(links,pic_id) else %> <div back> <a href="/pics.html#p-<%=pic.id%>"><img src="/images/keyboard_backspace.svg"></a> </div> <div msg> Your image has been saved. </div> <div body> <div pic> <img <%=pic.title_attr()%> src="<%=pic.get_url()%>"> <div> <button type=button small onclick="startChangePic()">Change</button> <button type=button small onclick="deletePic1(this)">Delete</button> </div> <div hashtags><%=pic.hashtags_html("pics.html")%></div> <form onsubmit="ajaxForm('/save_pic_title.js',this)" action="javascript:"> <input type=hidden name=pic value="<%=pic_id%>"> <label>Photo title</label> <div field> <input type=text required name=title placeholder="Title" value="<%= html_encode(pic.title or "") %>"> </div> <label>Hashtags</label> <div field> <textarea name=hashtags placeholder="#hashtag1 #hashtag2"><%= hashtags(pic) %></textarea> <div error=hashtags></div> </div> <div field> <label clickable><input type=checkbox name=visible <%=pic.is_hidden and "" or "checked"%>> Visible</label> </div> <button type=submit small>Save</button> <div error=success></div> </form> </div> <div outer_links> <% div_links(links,pic_id) %> </div> </div> <% end %> <% footer() %> </div> <script> dragInit(); </script> </body> </html> <% end