view src/pics.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 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