mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
feat: add social hub and stream cast modules with initialization, rendering, and scheduling functionalities
This commit is contained in:
48
packages/social_hub/seed/scripts/composer.lua
Normal file
48
packages/social_hub/seed/scripts/composer.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
-- Post composer utilities
|
||||
local M = {}
|
||||
|
||||
function M.render()
|
||||
return {
|
||||
type = "composer",
|
||||
children = {
|
||||
{
|
||||
type = "textarea",
|
||||
props = {
|
||||
placeholder = "What's on your mind?",
|
||||
name = "content",
|
||||
rows = 3
|
||||
}
|
||||
},
|
||||
{
|
||||
type = "composer_actions",
|
||||
children = {
|
||||
{ type = "button", props = { icon = "image", label = "Media" } },
|
||||
{ type = "button", props = { icon = "smile", label = "Emoji" } },
|
||||
{ type = "button", props = { variant = "primary", label = "Post" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function M.validate(content)
|
||||
if not content or content == "" then
|
||||
return { valid = false, error = "Post cannot be empty" }
|
||||
end
|
||||
if #content > 500 then
|
||||
return { valid = false, error = "Post too long (max 500 chars)" }
|
||||
end
|
||||
return { valid = true }
|
||||
end
|
||||
|
||||
function M.submit(content, media)
|
||||
return {
|
||||
action = "create_post",
|
||||
data = {
|
||||
content = content,
|
||||
media = media or {}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
41
packages/social_hub/seed/scripts/feed.lua
Normal file
41
packages/social_hub/seed/scripts/feed.lua
Normal file
@@ -0,0 +1,41 @@
|
||||
-- Social feed rendering
|
||||
local M = {}
|
||||
|
||||
function M.render_post(post)
|
||||
return {
|
||||
type = "feed_post",
|
||||
props = {
|
||||
id = post.id,
|
||||
author = post.author,
|
||||
avatar = post.avatar,
|
||||
content = post.content,
|
||||
timestamp = post.created_at,
|
||||
likes = post.likes or 0,
|
||||
comments = post.comments or 0
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function M.render_feed(posts)
|
||||
local items = {}
|
||||
for _, post in ipairs(posts) do
|
||||
table.insert(items, M.render_post(post))
|
||||
end
|
||||
return {
|
||||
type = "social_feed",
|
||||
children = items
|
||||
}
|
||||
end
|
||||
|
||||
function M.empty_state()
|
||||
return {
|
||||
type = "empty_state",
|
||||
props = {
|
||||
icon = "inbox",
|
||||
title = "No posts yet",
|
||||
message = "Be the first to share something!"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
15
packages/social_hub/seed/scripts/init.lua
Normal file
15
packages/social_hub/seed/scripts/init.lua
Normal file
@@ -0,0 +1,15 @@
|
||||
-- Social Hub initialization
|
||||
local M = {}
|
||||
|
||||
M.name = "social_hub"
|
||||
M.version = "1.0.0"
|
||||
|
||||
function M.init()
|
||||
return {
|
||||
name = M.name,
|
||||
version = M.version,
|
||||
loaded = true
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,34 +1,28 @@
|
||||
{
|
||||
"scripts": [
|
||||
{
|
||||
"id": "init",
|
||||
"name": "Social Hub Init",
|
||||
"file": "init.lua",
|
||||
"name": "init",
|
||||
"category": "lifecycle",
|
||||
"description": "Lifecycle hooks for package installation"
|
||||
"description": "Initialize social hub module"
|
||||
},
|
||||
{
|
||||
"file": "permissions.lua",
|
||||
"name": "permissions",
|
||||
"category": "security",
|
||||
"description": "Role-based access rules for posting and moderation"
|
||||
"id": "feed",
|
||||
"name": "Feed Rendering",
|
||||
"file": "feed.lua",
|
||||
"description": "Social feed post rendering"
|
||||
},
|
||||
{
|
||||
"file": "feed_rank.lua",
|
||||
"name": "feed_rank",
|
||||
"category": "ranking",
|
||||
"description": "Score feed items based on recency and engagement"
|
||||
"id": "composer",
|
||||
"name": "Post Composer",
|
||||
"file": "composer.lua",
|
||||
"description": "Create and publish posts"
|
||||
},
|
||||
{
|
||||
"file": "moderation.lua",
|
||||
"name": "moderation",
|
||||
"category": "moderation",
|
||||
"description": "Flag content for review using lightweight heuristics"
|
||||
},
|
||||
{
|
||||
"file": "analytics.lua",
|
||||
"name": "analytics",
|
||||
"category": "analytics",
|
||||
"description": "Aggregate engagement signals for dashboards"
|
||||
"id": "stats",
|
||||
"name": "Social Stats",
|
||||
"file": "stats.lua",
|
||||
"description": "Social statistics display"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
38
packages/social_hub/seed/scripts/stats.lua
Normal file
38
packages/social_hub/seed/scripts/stats.lua
Normal file
@@ -0,0 +1,38 @@
|
||||
-- Social statistics
|
||||
local M = {}
|
||||
|
||||
function M.render_stat(label, value, icon)
|
||||
return {
|
||||
type = "stat_card",
|
||||
props = {
|
||||
label = label,
|
||||
value = value,
|
||||
icon = icon
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function M.render_stats(data)
|
||||
return {
|
||||
type = "stats_grid",
|
||||
columns = 3,
|
||||
children = {
|
||||
M.render_stat("Followers", data.followers or 0, "users"),
|
||||
M.render_stat("Following", data.following or 0, "user-plus"),
|
||||
M.render_stat("Posts", data.posts or 0, "file-text")
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function M.render_hero(user)
|
||||
return {
|
||||
type = "hero_section",
|
||||
children = {
|
||||
{ type = "avatar", props = { src = user.avatar, size = "xl" } },
|
||||
{ type = "heading", props = { level = 1, text = user.name } },
|
||||
{ type = "text", props = { variant = "muted", text = user.bio } }
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
15
packages/stream_cast/seed/scripts/init.lua
Normal file
15
packages/stream_cast/seed/scripts/init.lua
Normal file
@@ -0,0 +1,15 @@
|
||||
-- Stream Cast initialization
|
||||
local M = {}
|
||||
|
||||
M.name = "stream_cast"
|
||||
M.version = "1.0.0"
|
||||
|
||||
function M.init()
|
||||
return {
|
||||
name = M.name,
|
||||
version = M.version,
|
||||
loaded = true
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,34 +1,28 @@
|
||||
{
|
||||
"scripts": [
|
||||
{
|
||||
"id": "init",
|
||||
"name": "Stream Cast Init",
|
||||
"file": "init.lua",
|
||||
"name": "init",
|
||||
"category": "lifecycle",
|
||||
"description": "Lifecycle hooks for installation and removal"
|
||||
"description": "Initialize stream cast module"
|
||||
},
|
||||
{
|
||||
"id": "player",
|
||||
"name": "Stream Player",
|
||||
"file": "player.lua",
|
||||
"description": "Video player controls"
|
||||
},
|
||||
{
|
||||
"id": "schedule",
|
||||
"name": "Stream Schedule",
|
||||
"file": "schedule.lua",
|
||||
"name": "schedule",
|
||||
"category": "automation",
|
||||
"description": "Resolve the next scene based on the run of show"
|
||||
"description": "Stream scheduling"
|
||||
},
|
||||
{
|
||||
"file": "scene_router.lua",
|
||||
"name": "scene_router",
|
||||
"category": "broadcast",
|
||||
"description": "Map scene names to output destinations"
|
||||
},
|
||||
{
|
||||
"file": "permissions.lua",
|
||||
"name": "permissions",
|
||||
"category": "security",
|
||||
"description": "Role checks for publishing and moderation"
|
||||
},
|
||||
{
|
||||
"file": "audience_pulse.lua",
|
||||
"name": "audience_pulse",
|
||||
"category": "analytics",
|
||||
"description": "Score audience engagement from live metrics"
|
||||
"id": "scenes",
|
||||
"name": "Scene Manager",
|
||||
"file": "scenes.lua",
|
||||
"description": "Stream scene management"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
48
packages/stream_cast/seed/scripts/player.lua
Normal file
48
packages/stream_cast/seed/scripts/player.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
-- Stream player controls
|
||||
local M = {}
|
||||
|
||||
M.PLAYING = "playing"
|
||||
M.PAUSED = "paused"
|
||||
M.BUFFERING = "buffering"
|
||||
M.OFFLINE = "offline"
|
||||
|
||||
function M.render(stream)
|
||||
return {
|
||||
type = "video_player",
|
||||
props = {
|
||||
src = stream.url,
|
||||
poster = stream.thumbnail,
|
||||
autoplay = true,
|
||||
controls = true
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function M.render_controls(state)
|
||||
return {
|
||||
type = "player_controls",
|
||||
children = {
|
||||
{ type = "button", props = { icon = state == M.PLAYING and "pause" or "play" } },
|
||||
{ type = "volume_slider", props = { min = 0, max = 100 } },
|
||||
{ type = "button", props = { icon = "maximize" } }
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function M.render_status(state, viewers)
|
||||
local colors = {
|
||||
playing = "success",
|
||||
paused = "warning",
|
||||
buffering = "info",
|
||||
offline = "error"
|
||||
}
|
||||
return {
|
||||
type = "status_bar",
|
||||
children = {
|
||||
{ type = "badge", props = { label = state, color = colors[state] } },
|
||||
{ type = "text", props = { text = viewers .. " viewers" } }
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
44
packages/stream_cast/seed/scripts/scenes.lua
Normal file
44
packages/stream_cast/seed/scripts/scenes.lua
Normal file
@@ -0,0 +1,44 @@
|
||||
-- Scene management
|
||||
local M = {}
|
||||
|
||||
function M.render_scene(scene)
|
||||
return {
|
||||
type = "scene_preview",
|
||||
props = {
|
||||
id = scene.id,
|
||||
name = scene.name,
|
||||
thumbnail = scene.thumbnail,
|
||||
active = scene.active or false
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function M.render_list(scenes)
|
||||
local items = {}
|
||||
for _, scene in ipairs(scenes) do
|
||||
table.insert(items, M.render_scene(scene))
|
||||
end
|
||||
return {
|
||||
type = "scene_list",
|
||||
children = items
|
||||
}
|
||||
end
|
||||
|
||||
function M.switch(scene_id)
|
||||
return {
|
||||
action = "switch_scene",
|
||||
scene_id = scene_id
|
||||
}
|
||||
end
|
||||
|
||||
function M.create(name, sources)
|
||||
return {
|
||||
action = "create_scene",
|
||||
data = {
|
||||
name = name,
|
||||
sources = sources or {}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
45
packages/stream_cast/seed/scripts/schedule.lua
Normal file
45
packages/stream_cast/seed/scripts/schedule.lua
Normal file
@@ -0,0 +1,45 @@
|
||||
-- Stream scheduling
|
||||
local M = {}
|
||||
|
||||
function M.render_item(stream)
|
||||
return {
|
||||
type = "schedule_item",
|
||||
props = {
|
||||
title = stream.title,
|
||||
start_time = stream.start_time,
|
||||
duration = stream.duration,
|
||||
thumbnail = stream.thumbnail
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function M.render_list(streams)
|
||||
local items = {}
|
||||
for _, stream in ipairs(streams) do
|
||||
table.insert(items, M.render_item(stream))
|
||||
end
|
||||
return {
|
||||
type = "schedule_list",
|
||||
children = items
|
||||
}
|
||||
end
|
||||
|
||||
function M.create(data)
|
||||
return {
|
||||
action = "schedule_stream",
|
||||
data = {
|
||||
title = data.title,
|
||||
start_time = data.start_time,
|
||||
duration = data.duration or 60
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function M.cancel(stream_id)
|
||||
return {
|
||||
action = "cancel_stream",
|
||||
stream_id = stream_id
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user