Mercurial Hosting > linkmystyle
view src/theme.html.luan @ 1:2776f06236b4
add source.html
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 11 Jul 2025 21:17:19 -0600 |
parents | 8f4df159f06b |
children |
line wrap: on
line source
local Luan = require "luan:Luan.luan" local error = Luan.error local pairs = Luan.pairs or error() local parse = Luan.parse or error() local Html = require "luan:Html.luan" local html_encode = Html.encode 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 fields = Shared.theme_fields or error() local User = require "site:/lib/User.luan" local get_background_img_url = User.get_background_img_url or error() local Logging = require "luan:logging/Logging.luan" local logger = Logging.logger "theme.html" local google_explanation = [[All Google fonts use this URL format. You can change the font name and edit the font URL to use other Google fonts not listed here.]] local fonts = { ["Sans-Serif"] = {} ["Times New Roman"] = {} ["Optima"] = {} ["Apple Chancery"] = {} ["Courier"] = {} ["Copperplate"] = {} ["Bitter"] = { title = "Google: Bitter" url = "https://fonts.googleapis.com/css?family=Bitter" explanation = google_explanation } ["Genos"] = { title = "Google: Genos" url = "https://fonts.googleapis.com/css?family=Genos" explanation = google_explanation } ["Emblema One"] = { title = "Google: Emblema One" url = "https://fonts.googleapis.com/css?family=Emblema+One" explanation = google_explanation } } for name, font in pairs(fonts) do font.name = name font.title = font.title or name font.url = font.url or "" font.explanation = font.explanation or "" end local function color_input(user_data,color) local value = user_data[color] value = value and html_encode(value) local default = fields[color] local v = value or default %> <div> <input type=color <%= v=="" and "" or [[value="]]..v..[["]] %> oninput="colorChange(this)"> <span color <%= v=="" and "" or [[style="background-color:]]..v..[["]] %> onclick="colorClick(this)"></span> <input type=text name="<%=color%>" value="<%= value or "" %>" placeholder="<%=default%>" onchange="colorInputChange(this)"> </div> <% end local function radio_input(user_data,name,value) local current = user_data[name] or fields[name] local checked = value==current and "checked" or "" %><input type=radio name="<%=name%>" value="<%=value%>" <%=checked%> ><% end return function() local user = User.current_required() if user==nil then return end local user_data = user.theme_data user_data = user_data and parse(user_data) or {} local message Io.stdout = Http.response.text_writer() %> <!doctype html> <html lang="en"> <head> <% head() %> <title>Link My Style</title> <style> <% for _, font in pairs(fonts) do if font.url ~= "" then %> @import "<%=font.url%>"; <% end %> <% end %> h1 { text-align: center; } div[body] { max-width: 600px; margin-left: auto; margin-right: auto; } @media (max-width: 700px) { div[body] { max-width: 90%; } } label { display: block; } form > div { display: flex; margin-top: 1px; margin-bottom: 10px; position: relative; } input[type="color"] { /* hide this useless modern piece of junk */ position: absolute; z-index: 1; width: 42.5px; height: 42.5px; cursor: pointer; opacity: 0; } span[color] { width: 42.5px; cursor: pointer; border: 1px solid #E0E0E0; } form span[pulldown] { border: 1px solid #E0E0E0; display: flex; align-items: center; } form span[pulldown] > span { padding: 4px; } span[shape] a { margin: 12px; padding: 12px 100px; border: 1px solid black; } span[shape] a:hover { text-decoration: none; } input[type="text"] { display: initial; margin: 0; border-radius: 0; } label[clickable] { border: 1px solid grey; padding: 4px; padding-right: 8px; } label[white] { color: white; background-color: black; } div[background_img] { gap: 8px; } button[background_img] { width: 42.5px; height: 42.5px; padding: 0; border: 1px solid #E0E0E0; } button[background_img] img { display: block; width: 100%; height: 100%; object-fit: cover; } div[background_img] button[small] { flex-grow: 1; background-color: #E0E0E0; color: black; } div[background_img] button[small]:hover { background-color: #C0C0C0; } div[font] { gap: 8px; } div[font] input[name="font"] { width: 33%; } div[font] input[name="font_url"] { width: 66%; } div[font_explanation] { color: #808080; } </style> <script> 'use strict'; function colorClick(colorSpan) { console.log('colorClick'); let colorInput = colorSpan.parentNode.querySelector('input[type="color"]'); colorInput.click(); } function colorChange(colorInput) { let parent = colorInput.parentNode; let color = colorInput.value; parent.querySelector('input[type="text"]').value = color; parent.querySelector('span[color]').style['background-color'] = color; } function colorInputChange(input) { let parent = input.parentNode; let color = input.value || input.placeholder; parent.querySelector('input[type="color"]').value = color; parent.querySelector('span[color]').style['background-color'] = color; } function setField(name,value) { document.querySelector('input[type="text"][name="'+name+'"]').value = value; } function setFont(font,url,explanation) { setField('font',font); setField('font_url',url); document.querySelector('div[font_explanation]').textContent = explanation; } function uploaded(uuid,filename) { document.querySelector('input[name="background_img_uuid"]').value = uuid; document.querySelector('input[name="background_img_filename"]').value = filename; document.querySelector('div[background_img] img').src = uploadcareUrl(uuid); } function clearImg() { document.querySelector('input[name="background_img_uuid"]').value = ''; document.querySelector('input[name="background_img_filename"]').value = ''; document.querySelector('div[background_img] img').src = '/images/nothing.svg'; } </script> </head> <body> <div full> <% body_header() %> <h1>My Theme</h1> <p top>Click the left side of every section to make quick changes or put exactly what you'd like in the input field. To remove a color or shadow, delete the text from the input field.</p> <div body> <form onsubmit="ajaxForm('/theme.js',this)" action="javascript:"> <label>Background Image</label> <div background_img> <button type=button background_img onclick="uploadcare.upload(uploaded)"> <img src="<%= get_background_img_url(user_data) or "/images/nothing.svg" %>" > </button> <input type=hidden name="background_img_uuid" value="<%= user_data.background_img_uuid or "" %>"> <input type=hidden name="background_img_filename" value="<%= user_data.background_img_filename or "" %>"> <button type=button small onclick="uploadcare.upload(uploaded)">Add</button> <button type=button small onclick="clearImg()">Clear</button> </div> <label>Background Color</label> <% color_input(user_data,"background_color") %> <label>Button Color</label> <% color_input(user_data,"link_background_color") %> <label>Button Hover Color</label> <% color_input(user_data,"link_hover_background_color") %> <label>Button Text Color</label> <% color_input(user_data,"link_text_color") %> <label>Title Color</label> <% color_input(user_data,"title_color") %> <label>Bio Color</label> <% color_input(user_data,"bio_color") %> <label>Social Icon Color</label> <div> <label clickable black><% radio_input(user_data,"icon_color","") %>Black</label> <label clickable white><% radio_input(user_data,"icon_color","white") %>White</label> </div> <label>Button Shape</label> <% local field = "link_border_radius" local value = user_data[field] value = value and html_encode(value) local default = fields[field] local value_or_default = value or default %> <div> <span shape pulldown> <span onclick="clickMenu(this)">Select...</span> <div pulldown_menu> <a style="border-radius:22px / 50%" href="javascript:setField('<%=field%>','22px / 50%')">Link</a> <a style="border-radius:12px / 50%" href="javascript:setField('<%=field%>','12px / 50%')">Link</a> <a style="border-radius:10px" href="javascript:setField('<%=field%>','10px')">Link</a> <a style="border-radius:0" href="javascript:setField('<%=field%>','0')">Link</a> <a style="border-radius:10px 100px" href="javascript:setField('<%=field%>','10px 100px')">Link</a> </div> </span> <input type=text name="<%=field%>" value="<%= value or "" %>" placeholder="<%=default%>"> </div> <label>Button Border Color</label> <% color_input(user_data,"link_border_color") %> <label>Button Shadow</label> <% local field = "link_shadow" local value = user_data[field] value = value and html_encode(value) local default = fields[field] local value_or_default = value or default %> <div> <span shape pulldown> <span onclick="clickMenu(this)">Select...</span> <div pulldown_menu> <a style="box-shadow:5px 5px 2px 1px" href="javascript:setField('<%=field%>','5px 5px 2px 1px')">Link</a> <a style="box-shadow:1px 1px 10px 1px" href="javascript:setField('<%=field%>','1px 1px 10px 1px')">Link</a> </div> </span> <input type=text name="<%=field%>" value="<%= value or "" %>" placeholder="<%=default%>"> </div> <label>Button Shadow Color</label> <% color_input(user_data,"link_shadow_color") %> <label>Font</label> <% local value = user_data.font value = value and html_encode(value) local value_url = user_data.font_url value_url = value_url and html_encode(value_url) local default = fields.font local explanation = fonts[value] and fonts[value].explanation or "" %> <div font> <span pulldown> <span onclick="clickMenu(this)">Select...</span> <div pulldown_menu> <% for _, font in pairs(fonts) do %> <a style="font-family:<%=font.name%>" href="javascript:setFont('<%=font.name%>','<%=font.url%>','<%=font.explanation%>')"><%=font.title%></a> <% end %> </div> </span> <input type=text name="font" value="<%= value or "" %>" placeholder="<%=default%>"> <input type=text name="font_url" value="<%= value_url or "" %>" placeholder="URL"> </div> <div font_explanation><%=explanation%></div> <button type=submit big>Save</button> <% local msg = message and message.info %> <div success><%= msg or "" %></div> </form> </div> <% footer() %> </div> </body> </html> <% end