mirror of
https://github.com/sune-org/store.git
synced 2026-01-13 16:17:58 +00:00
1 line
20 KiB
JSON
1 line
20 KiB
JSON
[{"id":"e9r2j2m","name":"Sune Forums (indev)","pinned":false,"avatar":"data:image/webp;base64,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","url":"gh://sune-org/store/forum.sune","updatedAt":1757539756302,"settings":{"model":"","temperature":"","top_p":"","top_k":"","frequency_penalty":"","repetition_penalty":"","min_p":"","top_a":"","verbosity":"","reasoning_effort":"default","system_prompt":"","html":"<div class=\"mx-auto max-w-2xl p-4 sm:p-6 font-sans text-stone-800\" x-data=\"suneForums()\" x-init=\"init()\">\n <!-- Header -->\n <header class=\"flex items-center justify-between mb-4 sm:mb-6 pb-3 border-b border-stone-200\">\n <div class=\"flex items-center gap-3\">\n <button x-show=\"view !== 'list'\" @click.prevent=\"goToList()\" class=\"h-9 w-9 flex-shrink-0 flex items-center justify-center rounded-full hover:bg-stone-100 transition-colors self-start mt-0.5\" aria-label=\"Back\">\n <i data-lucide=\"arrow-left\" class=\"h-5 w-5 text-stone-600\"></i>\n </button>\n <div>\n <h1 class=\"text-xl font-bold text-stone-900\" x-text=\"view === 'list' ? 'Sune Forums' : (view === 'new_post' ? 'Create a Post' : (currentPost ? currentPost.title : '...'))\"></h1>\n <p x-show=\"view === 'post' && currentPost\" class=\"text-xs text-stone-500 mt-0.5\">By <span class=\"font-medium\" x-text=\"currentPost.author_name\"></span> · <span x-text=\"formatDate(currentPost.created_at)\"></span></p>\n </div>\n </div>\n <div class=\"flex items-center gap-2\">\n <span class=\"text-xs text-stone-400\">v1.2.2</span>\n <button x-show=\"view === 'list'\" @click.prevent=\"view = 'new_post'\" class=\"px-3 py-1.5 text-sm font-semibold bg-black text-white rounded-md hover:bg-black/90 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2\">\n New Post\n </button>\n </div>\n </header>\n\n <!-- Error State -->\n <div x-show=\"error\" x-transition class=\"p-3 mb-4 bg-red-50 text-red-800 border border-red-200 rounded-lg\" x-text=\"error\"></div>\n\n <!-- Main Content Area -->\n <main class=\"relative\">\n <!-- Loading Overlay -->\n <div x-show=\"isLoading\" x-transition:enter=\"transition-opacity duration-300\" x-transition:leave=\"transition-opacity duration-300\" class=\"absolute inset-0 z-10 flex items-center justify-center pt-10\">\n <i data-lucide=\"loader-circle\" class=\"h-6 w-6 animate-spin text-stone-400\"></i>\n </div>\n \n <!-- Views -->\n <div :class=\"{'opacity-50 blur-sm pointer-events-none': isLoading}\">\n <!-- Posts List -->\n <div x-show=\"view === 'list'\" x-transition>\n <div class=\"space-y-2\">\n <template x-for=\"post in posts\" :key=\"post.id\">\n <a href=\"#\" @click.prevent=\"selectPost(post.id)\" class=\"block p-3 rounded-lg hover:bg-stone-100 transition-colors duration-200\">\n <p class=\"font-semibold text-stone-900\" x-text=\"post.title\"></p>\n <p class=\"text-xs text-stone-500 mt-1\">By <span class=\"font-medium\" x-text=\"post.author_name\"></span> · <span x-text=\"formatDate(post.created_at)\"></span></p>\n </a>\n </template>\n </div>\n </div>\n\n <!-- New Post Form -->\n <div x-show=\"view === 'new_post'\" x-transition class=\"p-1\">\n <form @submit.prevent=\"submitPost()\" class=\"space-y-3\">\n <input type=\"text\" x-model=\"newPost.title\" placeholder=\"Post Title\" required class=\"w-full px-3 py-2 bg-stone-100 rounded-md transition focus:bg-white focus:ring-2 focus:ring-black\">\n <textarea x-model=\"newPost.content\" placeholder=\"What's on your mind, Master?\" required rows=\"8\" @input=\"autoResize($el)\" class=\"w-full px-3 py-2 bg-stone-100 rounded-md transition resize-none focus:bg-white focus:ring-2 focus:ring-black\"></textarea>\n <div class=\"flex justify-end gap-2 pt-1\">\n <button type=\"button\" @click=\"goToList()\" class=\"px-4 py-2 font-semibold bg-stone-200 text-stone-800 rounded-md hover:bg-stone-300 transition-colors\">Cancel</button>\n <button type=\"submit\" class=\"px-4 py-2 font-semibold bg-black text-white rounded-md hover:bg-black/90 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2\">Post</button>\n </div>\n </form>\n </div>\n\n <!-- Single Post & Comments -->\n <div x-show=\"view === 'post' && currentPost\" x-transition class=\"space-y-6\">\n <article class=\"bg-stone-50 rounded-lg p-0\">\n <div class=\"markdown-body\" data-post-content x-html=\"render(currentPost.content)\"></div>\n </article>\n <section class=\"space-y-4\">\n <h2 class=\"text-lg font-bold text-stone-900 border-b border-stone-200 pb-2\">Comments</h2>\n <div x-show=\"currentPost.comments.length === 0\" class=\"text-sm text-stone-500 text-center py-4\">No comments yet.</div>\n <div class=\"space-y-3\">\n <template x-for=\"comment in currentPost.comments\" :key=\"comment.id\">\n <div class=\"p-3 bg-stone-50 rounded-lg\">\n <p class=\"text-xs text-stone-500 mb-1.5\"><span class=\"font-semibold text-stone-700\" x-text=\"comment.author_name\"></span> · <span x-text=\"formatDate(comment.created_at)\"></span></p>\n <div class=\"markdown-body\" :data-comment-id=\"comment.id\" x-html=\"render(comment.content)\"></div>\n </div>\n </template>\n </div>\n <form @submit.prevent=\"submitComment()\" class=\"pt-4 flex items-start gap-2\">\n <textarea x-model=\"newComment\" placeholder=\"Add a comment...\" required rows=\"1\" @input=\"autoResize($el)\" class=\"flex-1 resize-none px-3 py-2 bg-stone-100 rounded-md transition focus:bg-white focus:ring-2 focus:ring-black\"></textarea>\n <button type=\"submit\" class=\"shrink-0 px-4 py-2 font-semibold bg-black text-white rounded-md hover:bg-black/90 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2\">Reply</button>\n </form>\n </section>\n </div>\n </div>\n </main>\n</div>\n<script>\nfunction suneForums() {\n const k=window.SUNE.id+'-forums';\n return {\n view:'list',posts:[],currentPost:null,isLoading:!0,error:'',\n newPost:{title:'',content:''},newComment:'',\n md:window.markdownit({html:!1,breaks:!0,linkify:!0}),\n init(){\n const c=JSON.parse(localStorage.getItem(k))||{};\n this.newPost=c.newPost||{title:'',content:''};this.newComment=c.newComment||'';\n this.$watch('newPost',()=>this.saveState());this.$watch('newComment',()=>this.saveState());\n this.$watch('currentPost',(p)=>{if(p&&this.view==='post')this.$nextTick(()=>this.enhanceAllMarkdown())});\n this.fetchPosts()\n },\n saveState(){localStorage.setItem(k,JSON.stringify({newPost:this.newPost,newComment:this.newComment}))},\n async query(sql,p=[]){\n this.isLoading=!0;this.error='';\n try{\n const r=await fetch('https://d1p.awww.workers.dev',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({query:sql,params:p})});\n if(!r.ok){const d=await r.json().catch(()=>null);throw new Error(d?.error||`HTTP Error ${r.status}`)}\n const d=await r.json();if(d.error)throw new Error(d.details||d.error);return d.results\n }catch(e){this.error=e.message;console.error(e);return null}finally{this.isLoading=!1}\n },\n async fetchPosts(){const r=await this.query(\"SELECT id,author_name,title,created_at FROM posts ORDER BY created_at DESC\");if(r)this.posts=r},\n async selectPost(id){\n this.view='post';this.currentPost=null;\n const [p,c]=await Promise.all([this.query(\"SELECT * FROM posts WHERE id = ?\", [id]),this.query(\"SELECT * FROM comments WHERE post_id = ? ORDER BY created_at ASC\", [id])]);\n if(p&&p.length)this.currentPost={...p[0],comments:c||[]}\n },\n async submitPost(){\n const{title:t,content:c}=this.newPost;if(!t.trim()||!c.trim())return;\n const a=window.USER?.name||'Anonymous';\n await this.query(\"INSERT INTO posts(author_name,title,content)VALUES(?,?,?)\",[a,t.trim(),c.trim()]);\n if(!this.error){this.newPost={title:'',content:''};this.goToList()}\n },\n async submitComment(){\n const c=this.newComment.trim();if(!c||!this.currentPost)return;\n const a=window.USER?.name||'Anonymous';\n await this.query(\"INSERT INTO comments(post_id,author_name,content)VALUES(?,?,?)\",[this.currentPost.id,a,c]);\n if(!this.error){this.newComment='';await this.selectPost(this.currentPost.id)}\n },\n goToList(){this.view='list';this.currentPost=null;this.error='';this.fetchPosts()},\n formatDate(s){if(!s)return'';try{return new Date(s.replace(' ','T')+'Z').toLocaleDateString(undefined,{month:'short',day:'numeric'})}catch{return s}},\n render(t){return this.md.render(t||'')},\n autoResize(el){el.style.height='auto';el.style.height=(el.scrollHeight+2)+'px'},\n enhanceAllMarkdown(){\n if(!window.enhanceCodeBlocks)return;\n const postEl=this.$root.querySelector('[data-post-content]');\n if(postEl)window.enhanceCodeBlocks(postEl,!0);\n this.$root.querySelectorAll('[data-comment-id]').forEach(el=>window.enhanceCodeBlocks(el,!0))\n }\n }\n}\n</script>\n","extension_html":"<sune src='https://raw.githubusercontent.com/sune-org/store/refs/heads/main/sync.sune' private></sune>","hide_composer":true},"storage":{}}] |