diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pics.html.luan	Fri Jul 11 20:57:49 2025 -0600
@@ -0,0 +1,203 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+local ipairs = Luan.ipairs or error()
+local Table = require "luan:Table.luan"
+local concat = Table.concat or error()
+local Parsers = require "luan:Parsers.luan"
+local json_string = Parsers.json_string 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 get_hashtags_list = Shared.get_hashtags_list or error()
+local User = require "site:/lib/User.luan"
+local Pic = require "site:/lib/Pic.luan"
+local get_user_pics = Pic.get_user_pics or error()
+
+
+return function()
+	local user = User.current_required()
+	if user==nil then return end
+	local pics = get_user_pics(user.id)
+	local hashtags_list, hashtags_set = get_hashtags_list(pics)
+	Io.stdout = Http.response.text_writer()
+%>
+<!doctype html>
+<html lang="en">
+	<head>
+<%		head() %>
+		<title>Link My Style</title>
+		<style>
+			div[pics_body] {
+				width: 90%;
+				margin-left: auto;
+				margin-right: auto;
+			}
+			div[pics] > span {
+				position: relative;
+			}
+			div[pics] span > img {
+				position: absolute;
+				height: 25%;
+				top: 0;
+				left: 0;
+				background-color: white;
+				border: 1px solid lightgrey;
+				opacity: 0.3;
+				padding: 4px;
+				touch-action: none;
+			}
+			div[is_hidden] {
+				position: absolute;
+				top: 50%;
+				left: 50%;
+				transform: translate(-50%,-50%);
+				color: white;
+				background-color: black;
+				opacity: 0.5;
+				padding: 20px;
+			}
+			div[add] {
+				margin-top: 20px;
+				margin-bottom: 40px;
+				margin-left: auto;
+				margin-right: auto;
+				max-width: 600px;
+			}
+			div[add] > * {
+				margin-bottom: 8px;
+			}
+			button[big] {
+				margin-top: 5px;
+			}
+			div[hashtags] {
+				text-align: center;
+				margin-bottom: 20px;
+			}
+		</style>
+		<style hashtag></style>
+		<script>
+			'use strict';
+
+			function addPic(uuid,filename) {
+				let title = document.querySelector('input[name="title"]');
+				let visible = document.querySelector('input[name="visible"]');
+				let data = 'uuid=' + uuid + '&filename=' + encodeURIComponent(filename) + '&title=' + encodeURIComponent(title.value)
+				if( visible.checked )
+					data += '&visible=on';
+				ajax( '/add_pic.js', data );
+			}
+
+			function startAddPic() {
+				let title = document.querySelector('input[name="title"]');
+				if( !title.reportValidity() )
+					return;
+				uploadcare.cropprOptions = {};
+				uploadcare.upload(addPic);
+			}
+
+			dad.onDropped = function(event) {
+				let dragging = event.original;
+				if( iDragging === indexOf(dragging.parentNode.querySelectorAll(dropSelector),dragging) )
+					return;
+				let picId = dragging.getAttribute('pic');
+				let prev = dragging.previousElementSibling;
+				let prevId = prev && prev.getAttribute('pic');
+				ajax( '/move_pic.js?pic='+picId+'&prev='+prevId );
+			};
+
+			dad.whatToDrag = function(draggable) {
+				return draggable.parentNode;
+			};
+
+			function dragInit() {
+				dropSelector = 'span';
+				let items = document.querySelectorAll('div[pics] span > img');
+				for( let i=0; i<items.length; i++ ) {
+					let item = items[i];
+					dad.setDraggable(item);
+					dad.setDropzone(item.parentNode);
+				}
+			}
+
+			let hashtags = <%=json_string(hashtags_set)%>;
+
+			function selectHashtag(hashtag) {
+				let style = document.querySelector('style[hashtag]');
+				if( hashtags[hashtag] ) {
+					style.innerHTML = `
+						div[pics] > span {
+							display: none;
+						}
+						div[pics] > span.${hashtag} {
+							display: block;
+						}
+`					;
+					history.replaceState(null,null,`#${hashtag}`);
+				} else {
+					style.innerHTML = '';
+					history.replaceState(null,null,'pics.html');
+				}
+			}
+
+			function init() {
+				dragInit();
+				let hash = location.hash;
+				if( hash ) {
+					hash = hash.slice(1);  // remove '#'
+					if( hashtags[hash] ) {
+						let select = document.querySelector('[hashtags] select');
+						select.value = hash;
+						selectHashtag(hash);
+					}
+				}
+			}
+		</script>
+	</head>
+	<body>
+	<div full>
+<%		body_header() %>
+		<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>
+		<div pics_body>
+			<div add>
+				<input type=text required name=title placeholder="Photo title">
+				<label clickable><input type=checkbox name=visible checked> Visible</label>
+				<button type=button big onclick="startAddPic()">Add an image</button>
+			</div>
+<%	if #hashtags_list > 0 then %>
+			<div hashtags>
+				<span select>
+					<select onchange="selectHashtag(value)">
+						<option value="">All Photos</option>
+<%		for _, hashtag in ipairs(hashtags_list) do %>
+						<option value="<%=hashtag%>">#<%=hashtag%></option>
+<%		end %>
+					</select>
+				</span>
+			</div>
+<%	end %>
+			<div pics>
+<%	for _, pic in ipairs(pics) do
+		local pic_id = pic.id
+%>
+				<span pic="<%=pic_id%>" id="p-<%=pic_id%>" <%= pic.class or "" %> >
+					<a <%=pic.title_attr()%> href="/links.html?pic=<%=pic_id%>" draggable=false>
+						<img loading=lazy src="<%=pic.get_thumb_url()%>" draggable=false>
+<%		if pic.is_hidden then %>
+						<div is_hidden>Hidden</div>
+<%		end %>
+					</a>
+					<img src="/images/drag_indicator.svg">
+				</span>
+<%	end %>
+			</div>
+		</div>
+<%		footer() %>
+	</div>
+	<script> init(); </script>
+	</body>
+</html>
+<%
+end