diff --git a/packages/social_hub/seed/scripts/composer.lua b/packages/social_hub/seed/scripts/composer.lua new file mode 100644 index 000000000..95299cc35 --- /dev/null +++ b/packages/social_hub/seed/scripts/composer.lua @@ -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 diff --git a/packages/social_hub/seed/scripts/feed.lua b/packages/social_hub/seed/scripts/feed.lua new file mode 100644 index 000000000..c1075348d --- /dev/null +++ b/packages/social_hub/seed/scripts/feed.lua @@ -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 diff --git a/packages/social_hub/seed/scripts/init.lua b/packages/social_hub/seed/scripts/init.lua new file mode 100644 index 000000000..2ca782c36 --- /dev/null +++ b/packages/social_hub/seed/scripts/init.lua @@ -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 diff --git a/packages/social_hub/seed/scripts/manifest.json b/packages/social_hub/seed/scripts/manifest.json index cdece959a..844ffa6eb 100644 --- a/packages/social_hub/seed/scripts/manifest.json +++ b/packages/social_hub/seed/scripts/manifest.json @@ -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" } ] } diff --git a/packages/social_hub/seed/scripts/stats.lua b/packages/social_hub/seed/scripts/stats.lua new file mode 100644 index 000000000..aa61f96c6 --- /dev/null +++ b/packages/social_hub/seed/scripts/stats.lua @@ -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 diff --git a/packages/stream_cast/seed/scripts/init.lua b/packages/stream_cast/seed/scripts/init.lua new file mode 100644 index 000000000..4821d7b00 --- /dev/null +++ b/packages/stream_cast/seed/scripts/init.lua @@ -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 diff --git a/packages/stream_cast/seed/scripts/manifest.json b/packages/stream_cast/seed/scripts/manifest.json index 4c02d419c..de6076761 100644 --- a/packages/stream_cast/seed/scripts/manifest.json +++ b/packages/stream_cast/seed/scripts/manifest.json @@ -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" } ] } diff --git a/packages/stream_cast/seed/scripts/player.lua b/packages/stream_cast/seed/scripts/player.lua new file mode 100644 index 000000000..9f1abe7ec --- /dev/null +++ b/packages/stream_cast/seed/scripts/player.lua @@ -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 diff --git a/packages/stream_cast/seed/scripts/scenes.lua b/packages/stream_cast/seed/scripts/scenes.lua new file mode 100644 index 000000000..5dae53098 --- /dev/null +++ b/packages/stream_cast/seed/scripts/scenes.lua @@ -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 diff --git a/packages/stream_cast/seed/scripts/schedule.lua b/packages/stream_cast/seed/scripts/schedule.lua new file mode 100644 index 000000000..64c8f7b9f --- /dev/null +++ b/packages/stream_cast/seed/scripts/schedule.lua @@ -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