Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .lute/build.luau
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ local context: BuildContext = {

api = {
secure = channel == "prod",
host = process.env.API_HOST,
host = if channel == "prod" then process.env.API_HOST else "localhost:8787",
},

discord = {
Expand Down
2 changes: 1 addition & 1 deletion backend/src/routes/gh_redirect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::extractors::{Edge, WorkerContext};
use crate::posthog;

const DEFAULT_POSTHOG_HOST: &str = "https://us.i.posthog.com";
const GITHUB_REPO_URL: &str = "https://github.com/grilme99/studio-activity";
const GITHUB_REPO_URL: &str = "https://github.com/BrookenRecord/studio-activity";

#[allow(clippy::must_use_candidate)]
#[tracing::instrument(
Expand Down
65 changes: 65 additions & 0 deletions plugin/src/ActivityPreview/ActivityButtons.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
local Plugin = script:FindFirstAncestor("StudioActivity")

local Packages = Plugin.Packages
local Foundation = require(Packages.Foundation)
local React = require(Packages.React)
local ReactUtils = require(Packages.ReactUtils)

local Types = require(script.Parent.Types)

local View = Foundation.View
local Button = Foundation.Button
local Tooltip = Foundation.Tooltip
local InputSize = Foundation.Enums.InputSize
local ButtonVariant = Foundation.Enums.ButtonVariant
local FillBehavior = Foundation.Enums.FillBehavior
local PopoverAlign = Foundation.Enums.PopoverAlign
local PopoverSide = Foundation.Enums.PopoverSide

local createNextOrder = ReactUtils.createNextOrder

local e = React.createElement

local function NOOP() end

type Props = {
buttons: { Types.ActivityButton },
LayoutOrder: number?,
}

local function ActivityButtons(props: Props)
local nextOrder = createNextOrder()

local buttonChildren: { React.ReactNode } = {}
for index, button in props.buttons do
table.insert(
buttonChildren,
e(Button, {
text = button.label,
key = tostring(index),
size = InputSize.Small,
variant = if index == 1 then ButtonVariant.SoftEmphasis else ButtonVariant.Standard,
fillBehavior = FillBehavior.Fill,
width = UDim.new(1, 0),
LayoutOrder = index,
onActivated = NOOP,
})
)
end

return e(Tooltip, {
title = if #props.buttons == 1
then "You won't see this button on your own profile"
else "You won't see these buttons on your own profile",
align = PopoverAlign.Center,
side = PopoverSide.Top,
LayoutOrder = props.LayoutOrder,
}, {
ButtonsContainer = e(View, {
tag = "size-full-0 auto-y col gap-small",
LayoutOrder = nextOrder(),
}, buttonChildren),
})
end

return ActivityButtons
6 changes: 6 additions & 0 deletions plugin/src/ActivityPreview/ActivityPreview.luau
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ local Foundation = require(Packages.Foundation)
local React = require(Packages.React)
local ReactUtils = require(Packages.ReactUtils)

local ActivityButtons = require(script.Parent.ActivityButtons)
local ActivityDetails = require(script.Parent.ActivityDetails)
local ActivityImage = require(script.Parent.ActivityImage)
local ActivityTimer = require(script.Parent.ActivityTimer)
Expand Down Expand Up @@ -68,6 +69,11 @@ local function ActivityPreview(props: Props)
}),
}),
}),

ActivityButtons = (props.activity.buttons and #props.activity.buttons > 0) and e(ActivityButtons, {
buttons = props.activity.buttons,
LayoutOrder = nextOrder(),
}),
})
end

Expand Down
6 changes: 6 additions & 0 deletions plugin/src/ActivityPreview/Types.luau
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export type ActivityButton = {
label: string,
url: string,
}

export type ActivityAssets = {
largeImage: string?,
largeText: string?,
Expand All @@ -11,6 +16,7 @@ export type Activity = {
detailsUrl: string?,
state: string?,
stateUrl: string?,
buttons: { ActivityButton }?,
startedAt: number?,
assets: ActivityAssets?,
}
Expand Down
3 changes: 2 additions & 1 deletion plugin/src/Api/AppAssetsStore.luau
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local Charm = require(Packages.Charm)
local BuildVars = require(Plugin.Source.BuildVars)
local DiscordApi = require(Plugin.Source.Api.Discord)
local Logger = require(Plugin.Source.Logger)
local createSingleton = require(Plugin.Source.Common.createSingleton)

type ApplicationAsset = DiscordApi.ApplicationAsset

Expand Down Expand Up @@ -60,7 +61,7 @@ local function createAppAssetsStore(discord: DiscordApi.DiscordApi)
end

return {
get = Charm.computed(function()
get = createSingleton(function()
local discord = DiscordApi.new({
clientId = BuildVars.discord.clientId,
})
Expand Down
6 changes: 2 additions & 4 deletions plugin/src/Authentication/AccountStore/init.luau
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
local Plugin = script:FindFirstAncestor("StudioActivity")

local Packages = Plugin.Packages
local Charm = require(Packages.Charm)

local BuildVars = require(Plugin.Source.BuildVars)
local DiscordApi = require(Plugin.Source.Api.Discord)
local createAccountStore = require(script.createAccountStore)
local createSingleton = require(Plugin.Source.Common.createSingleton)

return table.freeze({
get = Charm.computed(function()
get = createSingleton(function()
local discord = DiscordApi.new({
clientId = BuildVars.discord.clientId,
})
Expand Down
4 changes: 2 additions & 2 deletions plugin/src/Authentication/AuthStore.luau
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
local Plugin = script:FindFirstAncestor("StudioActivity")

local Packages = Plugin.Packages
local Charm = require(Packages.Charm)
local t = require(Packages.t)

local createPluginSettingsStore = require(Plugin.Source.Plugin.createPluginSettingsStore)
local createSingleton = require(Plugin.Source.Common.createSingleton)

export type Account = {
accessToken: string,
Expand Down Expand Up @@ -34,7 +34,7 @@ local validate = t.interface({
})

return {
get = Charm.computed(function()
get = createSingleton(function()
return createPluginSettingsStore("PresenceAuthStore", defaultValue, validate)
end),
}
8 changes: 8 additions & 0 deletions plugin/src/Common/Constants.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
local Constants = {}

local REDIRECT_BASE =
"https://activity.brooke.sh/?utm_source=discord&utm_medium=rich_presence&utm_campaign=studio_activity"
Constants.PLUGIN_LINK_PROFILE_LINK = `{REDIRECT_BASE}&utm_content=profile_link`
Constants.PLUGIN_LINK_PROFILE_BUTTON = `{REDIRECT_BASE}&utm_content=profile_button`

return table.freeze(Constants)
44 changes: 44 additions & 0 deletions plugin/src/Common/createSingleton.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
local Plugin = script:FindFirstAncestor("StudioActivity")

local Packages = Plugin.Packages
local Charm = require(Packages.Charm)

--[[
Returns a lazy getter for a singleton store. The factory is invoked on
first call and the result is cached forever. The factory runs inside
`Charm.untracked`, so any signal reads or writes performed during the
store's own initialization do NOT register as dependencies of whichever
reactive context (effect / computed / React render) happened to make the
first call. The returned store is still fully reactive at the method
level — its internal signals and computeds keep working as normal.

Without this, a factory that synchronously reads and writes one of its
own internal signals during init (e.g. `createPlaceDetailsStore` calling
`prefetchPlaceIds(game.PlaceId)`) would link that signal as a dependency
of the calling reactive context, and every subsequent mutation of the
signal would cause the caller to re-evaluate — constructing a brand new
store and feeding back into the same cycle.
]]
local function createSingleton<T>(factory: () -> T): () -> T
local instance: T? = nil
local initializing = false

return function(): T
if instance ~= nil then
return instance :: T
end
if initializing then
error("createSingleton: recursive factory invocation detected", 2)
end
initializing = true
local ok, result = pcall(Charm.untracked, factory)
initializing = false
if not ok then
error(result, 2)
end
instance = result
return instance :: T
end
end

return createSingleton
110 changes: 0 additions & 110 deletions plugin/src/CustomProfile/ActivityFields.luau

This file was deleted.

11 changes: 3 additions & 8 deletions plugin/src/CustomProfile/CustomProfile.luau
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ local Foundation = require(Packages.Foundation)
local React = require(Packages.React)
local ReactUtils = require(Packages.ReactUtils)

local ActivityFields = require(script.Parent.ActivityFields)
local GameOverride = require(script.Parent.GameOverride)
local ModalStore = require(Plugin.Source.Modal.ModalStore)
local PreviewBlock = require(script.Parent.PreviewBlock)
local ProfileActions = require(script.Parent.ProfileActions)
local ProfileContext = require(script.Parent.ProfileContext)
local ProfileName = require(script.Parent.ProfileName)
local SettingsList = require(script.Parent.SettingsList)
local Title = require(script.Parent.Title)

local View = Foundation.View
Expand Down Expand Up @@ -91,7 +90,7 @@ local function CustomProfileSheet(props: SheetProps)

Content = e(Sheet.Content, nil, {
Container = e(View, {
tag = "size-full-0 auto-y col padding-y-small",
tag = "size-full-0 auto-y col padding-top-small",
LayoutOrder = nextOrder(),
}, {
PreviewBlock = e(PreviewBlock, {
Expand All @@ -102,11 +101,7 @@ local function CustomProfileSheet(props: SheetProps)
LayoutOrder = nextOrder(),
}),

ActivityFields = e(ActivityFields, {
LayoutOrder = nextOrder(),
}),

GameOverride = e(GameOverride, {
SettingsList = e(SettingsList, {
LayoutOrder = nextOrder(),
}),
}),
Expand Down
Loading
Loading