Skip to content

Commit

Permalink
About page (#252)
Browse files Browse the repository at this point in the history
This PR adds an About page with information on the current flipbook
version.

Copyright year auto updates based on current year, and authors are
loaded based on user ID.


Dark theme | Light theme
--- | ---
<img width="419" alt="Screenshot 2024-05-27 at 6 35 46 PM"
src="https://github.com/flipbook-labs/flipbook/assets/3081936/3d5371c5-0148-43f0-9e26-e81a4759e517">
| <img width="440" alt="Screenshot 2024-05-27 at 6 35 35 PM"
src="https://github.com/flipbook-labs/flipbook/assets/3081936/334c77b9-ee13-4f22-a7c4-1e051e648138">





# Checklist

- [ ] Ran `lune run test` locally before merging
  • Loading branch information
vocksel authored Nov 3, 2024
1 parent eb289ed commit 5daea9c
Show file tree
Hide file tree
Showing 15 changed files with 421 additions and 139 deletions.
5 changes: 4 additions & 1 deletion build.project.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"Example": {
"$path": "example"
},
"wally.toml": {
"$path": "wally.toml"
},
"$path": "src"
}
}
}
5 changes: 4 additions & 1 deletion default.project.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"Packages": {
"$path": "Packages"
},
"wally.toml": {
"$path": "wally.toml"
},
"$path": "build"
}
}
}
Binary file added img/GitHubMark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
147 changes: 147 additions & 0 deletions src/About/AboutView.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
local React = require("@pkg/React")

local RobloxProfile = require("@root/About/RobloxProfile")
local Sprite = require("@root/Common/Sprite")
local assets = require("@root/assets")
local nextLayoutOrder = require("@root/Common/nextLayoutOrder")
local useTheme = require("@root/Common/useTheme")
local wally = require(script.Parent.Parent["wally.toml"])

local useMemo = React.useMemo

local AUTHOR_USER_IDS = {
1343930,
731053179,
}

local function AboutView()
local theme = useTheme()
local currentYear = useMemo(function()
return (DateTime.now():ToUniversalTime() :: any).Year
end, {})

local authors: { [string]: React.Node } = {}
for _, userId in AUTHOR_USER_IDS do
authors[`Author{userId}`] = React.createElement(RobloxProfile, {
userId = userId,
LayoutOrder = nextLayoutOrder(),
})
end

return React.createElement("Frame", {
Size = UDim2.fromScale(1, 1),
BackgroundColor3 = theme.background,
BorderSizePixel = 0,
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
HorizontalAlignment = Enum.HorizontalAlignment.Center,
Padding = theme.paddingLarge,
}),

Padding = React.createElement("UIPadding", {
PaddingTop = theme.paddingLarge,
PaddingRight = theme.paddingLarge,
PaddingBottom = theme.paddingLarge,
PaddingLeft = theme.paddingLarge,
}),

Logo = React.createElement(Sprite, {
layoutOrder = nextLayoutOrder(),
image = assets.IconLight,
size = UDim2.fromOffset(42, 42),
}),

Title = React.createElement("TextLabel", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
Font = theme.font,
LayoutOrder = nextLayoutOrder(),
Size = UDim2.fromScale(0, 0),
Text = `flipbook v{wally.package.version}`,
TextColor3 = theme.text,
TextSize = theme.headerTextSize,
TextWrapped = true,
}),

GitHub = React.createElement("Frame", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
LayoutOrder = nextLayoutOrder(),
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
FillDirection = Enum.FillDirection.Horizontal,
Padding = theme.paddingSmall,
}),

Icon = React.createElement(Sprite, {
layoutOrder = nextLayoutOrder(),
color = theme.github,
image = assets.GitHubMark,
size = UDim2.fromOffset(theme.textSize, theme.textSize),
}),

Label = React.createElement("TextLabel", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
Font = theme.font,
LayoutOrder = nextLayoutOrder(),
Size = UDim2.fromScale(0, 0),
Text = "flipbook-labs/flipbook",
TextColor3 = theme.text,
TextSize = theme.textSize,
}),
}),

Authors = React.createElement("Frame", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
LayoutOrder = nextLayoutOrder(),
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
HorizontalAlignment = Enum.HorizontalAlignment.Center,
Padding = theme.padding,
}),

Title = React.createElement("TextLabel", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
Font = theme.font,
LayoutOrder = nextLayoutOrder(),
Size = UDim2.fromScale(0, 0),
Text = `Created by:`,
TextColor3 = theme.text,
TextSize = theme.textSize,
TextWrapped = true,
}),

AuthorList = React.createElement("Frame", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
LayoutOrder = nextLayoutOrder(),
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
FillDirection = Enum.FillDirection.Horizontal,
Padding = theme.padding,
}),
}, authors),
}),

Copy = React.createElement("TextLabel", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
Font = theme.font,
LayoutOrder = nextLayoutOrder(),
Size = UDim2.fromScale(0, 0),
Text = `Copyright © 2021—{currentYear} flipbook-labs`,
TextColor3 = theme.text,
TextSize = theme.textSize,
TextWrapped = true,
}),
})
end

return AboutView
15 changes: 15 additions & 0 deletions src/About/AboutView.story.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
local React = require("@pkg/React")

local AboutView = require("./AboutView")
local ContextProviders = require("@root/Common/ContextProviders")
local MockPlugin = require("@root/Testing/MockPlugin")

return {
story = function()
return React.createElement(ContextProviders, {
plugin = MockPlugin.new(),
}, {
AboutView = React.createElement(AboutView),
})
end,
}
79 changes: 79 additions & 0 deletions src/About/RobloxProfile.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
local Players = game:GetService("Players")

local React = require("@pkg/React")
local ReactSpring = require("@pkg/ReactSpring")

local nextLayoutOrder = require("@root/Common/nextLayoutOrder")
local useTheme = require("@root/Common/useTheme")

local useState = React.useState
local useEffect = React.useEffect

local AVATAR_SIZE = Enum.ThumbnailSize.Size48x48

export type Props = {
userId: number,
LayoutOrder: number?,
}

local function RobloxProfile(props: Props)
local theme = useTheme()
local avatar, setAvatar = useState(nil :: string?)
local username, setUsername = useState(nil :: string?)

local isLoading = avatar == nil and username == nil

local styles = ReactSpring.useSpring({
alpha = if isLoading then 1 else 0,
})

useEffect(function()
task.spawn(function()
setAvatar(Players:GetUserThumbnailAsync(props.userId, Enum.ThumbnailType.HeadShot, AVATAR_SIZE))
end)

task.spawn(function()
setUsername(Players:GetNameFromUserIdAsync(props.userId))
end)
end, { props.userId })

return React.createElement("Frame", {
LayoutOrder = props.LayoutOrder,
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
FillDirection = Enum.FillDirection.Horizontal,
VerticalAlignment = Enum.VerticalAlignment.Center,
Padding = theme.paddingSmall,
}),

Avatar = React.createElement("ImageLabel", {
LayoutOrder = nextLayoutOrder(),
Size = UDim2.fromOffset(48, 48),
BackgroundColor3 = theme.sidebar,
BackgroundTransparency = 0.6,
ImageTransparency = styles.alpha,
BorderSizePixel = 0,
Image = avatar,
}, {
Corner = React.createElement("UICorner", {
CornerRadius = UDim.new(0.5, 0),
}),
}),

Username = React.createElement("TextLabel", {
LayoutOrder = nextLayoutOrder(),
Text = `@{username}`,
Font = theme.font,
TextColor3 = theme.text,
TextSize = theme.textSize,
BackgroundTransparency = 1,
TextTransparency = styles.alpha,
AutomaticSize = Enum.AutomaticSize.XY,
}),
})
end

return RobloxProfile
27 changes: 27 additions & 0 deletions src/About/RobloxProfile.story.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
local React = require("@pkg/React")

local ContextProviders = require("@root/Common/ContextProviders")
local MockPlugin = require("@root/Testing/MockPlugin")
local RobloxProfile = require("./RobloxProfile")

local controls = {
userId = 1,
}

type Props = {
controls: typeof(controls),
}
return {
controls = controls,
story = function(props: Props)
local userId = assert(tonumber(props.controls.userId))

return React.createElement(ContextProviders, {
plugin = MockPlugin.new(),
}, {
RobloxProfiler = React.createElement(RobloxProfile, {
userId = userId,
}),
})
end,
}
1 change: 1 addition & 0 deletions src/Navigation/NavigationContext.luau
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export type NavigationContext = {
navigateTo: (newScreen: Screen) -> (),
goBack: () -> (),
getBreadcrumbs: () -> { string },
canGoBack: () -> boolean,
currentScreen: Screen,
}

Expand Down
5 changes: 4 additions & 1 deletion src/Navigation/Screen.luau
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local ModuleLoader = require("@pkg/ModuleLoader")
local React = require("@pkg/React")

local AboutView = require("@root/About/AboutView")
local NavigationContext = require("@root/Navigation/NavigationContext")
local SettingsView = require("@root/UserSettings/SettingsView")
local StoryCanvas = require("@root/Storybook/StoryCanvas")
Expand Down Expand Up @@ -32,8 +33,10 @@ local function Screen(props: Props)
end
elseif currentScreen == "Settings" then
return React.createElement(SettingsView)
elseif currentScreen == "About" then
return React.createElement(AboutView)
end
return nil
return nil :: never
end, { props, currentScreen } :: { unknown })

return screenElement
Expand Down
3 changes: 2 additions & 1 deletion src/Navigation/enums.luau
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
local enums = {}

export type Screen = "Home" | "Settings"
export type Screen = "Home" | "Settings" | "About"
enums.Screen = {
Home = "Home" :: Screen,
Settings = "Settings" :: Screen,
About = "About" :: Screen,
}

return enums
Loading

0 comments on commit 5daea9c

Please sign in to comment.