Advertisement
Vortex23

ThemeManager

Aug 13th, 2024 (edited)
15,001
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.72 KB | None | 0 0
  1. local cloneref = cloneref or function(o) return o end
  2. local httpService = cloneref(game:GetService('HttpService'))
  3. local httprequest = (syn and syn.request) or (http and http.request) or http_request or (fluxus and fluxus.request) or request
  4. local getassetfunc = getcustomasset or getsynasset
  5. local ThemeManager = {} do
  6.     ThemeManager.Folder = 'LinoriaLibSettings'
  7.     -- if not isfolder(ThemeManager.Folder) then makefolder(ThemeManager.Folder) end
  8.  
  9.     ThemeManager.Library = nil
  10.     ThemeManager.BuiltInThemes = {
  11.         ['Default']         = { 1, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"1c1c1c","AccentColor":"0055ff","BackgroundColor":"141414","OutlineColor":"323232"}') },
  12.         ['BBot']            = { 2, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"1e1e1e","AccentColor":"7e48a3","BackgroundColor":"232323","OutlineColor":"141414"}') },
  13.         ['Fatality']        = { 3, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"1e1842","AccentColor":"c50754","BackgroundColor":"191335","OutlineColor":"3c355d"}') },
  14.         ['Jester']          = { 4, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"242424","AccentColor":"db4467","BackgroundColor":"1c1c1c","OutlineColor":"373737"}') },
  15.         ['Mint']            = { 5, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"242424","AccentColor":"3db488","BackgroundColor":"1c1c1c","OutlineColor":"373737"}') },
  16.         ['Tokyo Night']     = { 6, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"191925","AccentColor":"6759b3","BackgroundColor":"16161f","OutlineColor":"323232"}') },
  17.         ['Ubuntu']          = { 7, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"3e3e3e","AccentColor":"e2581e","BackgroundColor":"323232","OutlineColor":"191919"}') },
  18.         ['Quartz']          = { 8, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"232330","AccentColor":"426e87","BackgroundColor":"1d1b26","OutlineColor":"27232f"}') },
  19.         ['Kiriot Hub']      = { 9, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"30333b","AccentColor":"ffaa00","BackgroundColor":"1a1c20","OutlineColor":"141414"}') },
  20.         ['Green']           = { 10, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"141414","AccentColor":"00ff8b","BackgroundColor":"1c1c1c","OutlineColor":"3c3c3c"}') },
  21.         ['Dracula']         = { 11, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"232533","AccentColor":"6271a5","BackgroundColor":"1b1c27","OutlineColor":"7c82a7"}') },
  22.     }
  23.  
  24.     function ApplyBackgroundVideo(webmLink)
  25.         if writefile == nil then return end;if readfile == nil then return end;if isfile == nil then return end
  26.         if ThemeManager.Library == nil then return end
  27.         if ThemeManager.Library.InnerVideoBackground == nil then return end
  28.  
  29.         if string.sub(tostring(webmLink), -5) == ".webm" then
  30.             local CurrentSaved = ""
  31.             if isfile(ThemeManager.Folder .. '/themes/currentVideoLink.txt') then
  32.                 CurrentSaved = readfile(ThemeManager.Folder .. '/themes/currentVideoLink.txt')
  33.             end
  34.             local VideoData = nil;
  35.             if CurrentSaved == tostring(webmLink) then
  36.                 VideoData = {
  37.                     Success = true,
  38.                     Body = nil
  39.                 }
  40.             else
  41.                 VideoData = httprequest({
  42.                     Url = tostring(webmLink),
  43.                     Method = 'GET'
  44.                 })
  45.             end
  46.            
  47.             if (VideoData.Success) then
  48.                 VideoData = VideoData.Body
  49.                 if (isfile(ThemeManager.Folder .. '/themes/currentVideo.webm') == false and VideoData ~= nil) or VideoData ~= nil then
  50.                     writefile(ThemeManager.Folder .. '/themes/currentVideo.webm', VideoData)
  51.                     writefile(ThemeManager.Folder .. '/themes/currentVideoLink.txt', tostring(webmLink))
  52.                 end
  53.                
  54.                 local Video = getassetfunc(ThemeManager.Folder .. '/themes/currentVideo.webm')
  55.                 ThemeManager.Library.InnerVideoBackground.Video = Video
  56.                 ThemeManager.Library.InnerVideoBackground.Visible = true
  57.                 ThemeManager.Library.InnerVideoBackground:Play()
  58.             end
  59.         end
  60.     end
  61.    
  62.     function ThemeManager:ApplyTheme(theme)
  63.         local customThemeData = self:GetCustomTheme(theme)
  64.         local data = customThemeData or self.BuiltInThemes[theme]
  65.  
  66.         if not data then return end
  67.  
  68.         -- custom themes are just regular dictionaries instead of an array with { index, dictionary }
  69.         if self.Library.InnerVideoBackground ~= nil then
  70.             self.Library.InnerVideoBackground.Visible = false
  71.         end
  72.        
  73.         local scheme = data[2]
  74.         for idx, col in next, customThemeData or scheme do
  75.             if idx ~= "VideoLink" then
  76.                 self.Library[idx] = Color3.fromHex(col)
  77.                
  78.                 if getgenv().Linoria.Options[idx] then
  79.                     getgenv().Linoria.Options[idx]:SetValueRGB(Color3.fromHex(col))
  80.                 end
  81.             else
  82.                 self.Library[idx] = col
  83.                
  84.                 if getgenv().Linoria.Options[idx] then
  85.                     getgenv().Linoria.Options[idx]:SetValue(col)
  86.                 end
  87.                
  88.                 ApplyBackgroundVideo(col)
  89.             end
  90.         end
  91.  
  92.         self:ThemeUpdate()
  93.     end
  94.  
  95.     function ThemeManager:ThemeUpdate()
  96.         -- This allows us to force apply themes without loading the themes tab :)
  97.         if self.Library.InnerVideoBackground ~= nil then
  98.             self.Library.InnerVideoBackground.Visible = false
  99.         end
  100.        
  101.         local options = { "FontColor", "MainColor", "AccentColor", "BackgroundColor", "OutlineColor", "VideoLink" }
  102.         for i, field in next, options do
  103.             if getgenv().Linoria.Options and getgenv().Linoria.Options[field] then
  104.                 self.Library[field] = getgenv().Linoria.Options[field].Value
  105.                 if field == "VideoLink" then
  106.                     ApplyBackgroundVideo(getgenv().Linoria.Options[field].Value)
  107.                 end
  108.             end
  109.         end
  110.  
  111.         self.Library.AccentColorDark = self.Library:GetDarkerColor(self.Library.AccentColor);
  112.         self.Library:UpdateColorsUsingRegistry()
  113.     end
  114.  
  115.     function ThemeManager:LoadDefault()    
  116.         local theme = 'Default'
  117.         local content = isfile(self.Folder .. '/themes/default.txt') and readfile(self.Folder .. '/themes/default.txt')
  118.  
  119.         local isDefault = true
  120.         if content then
  121.             if self.BuiltInThemes[content] then
  122.                 theme = content
  123.             elseif self:GetCustomTheme(content) then
  124.                 theme = content
  125.                 isDefault = false;
  126.             end
  127.         elseif self.BuiltInThemes[self.DefaultTheme] then
  128.         theme = self.DefaultTheme
  129.         end
  130.  
  131.         if isDefault then
  132.             getgenv().Linoria.Options.ThemeManager_ThemeList:SetValue(theme)
  133.         else
  134.             self:ApplyTheme(theme)
  135.         end
  136.     end
  137.  
  138.     function ThemeManager:SaveDefault(theme)
  139.         writefile(self.Folder .. '/themes/default.txt', theme)
  140.     end
  141.  
  142.     function ThemeManager:Delete(name)
  143.         if (not name) then
  144.             return false, 'no config file is selected'
  145.         end
  146.        
  147.         local file = self.Folder .. '/themes/' .. name
  148.         if not isfile(file) then return false, 'invalid file' end
  149.  
  150.         local success, decoded = pcall(delfile, file)
  151.         if not success then return false, 'delete file error' end
  152.        
  153.         return true
  154.     end
  155.    
  156.     function ThemeManager:CreateThemeManager(groupbox)
  157.         groupbox:AddLabel('Background color'):AddColorPicker('BackgroundColor', { Default = self.Library.BackgroundColor });
  158.         groupbox:AddLabel('Main color') :AddColorPicker('MainColor', { Default = self.Library.MainColor });
  159.         groupbox:AddLabel('Accent color'):AddColorPicker('AccentColor', { Default = self.Library.AccentColor });
  160.         groupbox:AddLabel('Outline color'):AddColorPicker('OutlineColor', { Default = self.Library.OutlineColor });
  161.         groupbox:AddLabel('Font color') :AddColorPicker('FontColor', { Default = self.Library.FontColor });
  162.         groupbox:AddInput('VideoLink', { Text = '.webm Video Background (Link)', Default = self.Library.VideoLink });
  163.        
  164.         local ThemesArray = {}
  165.         for Name, Theme in next, self.BuiltInThemes do
  166.             table.insert(ThemesArray, Name)
  167.         end
  168.  
  169.         table.sort(ThemesArray, function(a, b) return self.BuiltInThemes[a][1] < self.BuiltInThemes[b][1] end)
  170.  
  171.         groupbox:AddDivider()
  172.  
  173.         groupbox:AddDropdown('ThemeManager_ThemeList', { Text = 'Theme list', Values = ThemesArray, Default = 1 })
  174.         groupbox:AddButton('Set as default', function()
  175.             self:SaveDefault(getgenv().Linoria.Options.ThemeManager_ThemeList.Value)
  176.             self.Library:Notify(string.format('Set default theme to %q', getgenv().Linoria.Options.ThemeManager_ThemeList.Value))
  177.         end)
  178.  
  179.         getgenv().Linoria.Options.ThemeManager_ThemeList:OnChanged(function()
  180.             self:ApplyTheme(getgenv().Linoria.Options.ThemeManager_ThemeList.Value)
  181.         end)
  182.  
  183.         groupbox:AddDivider()
  184.  
  185.         groupbox:AddInput('ThemeManager_CustomThemeName', { Text = 'Custom theme name' })
  186.         groupbox:AddButton('Create theme', function()
  187.             if Options.ThemeManager_CustomThemeName.Value ~= '' then
  188.                 self:SaveCustomTheme(getgenv().Linoria.Options.ThemeManager_CustomThemeName.Value..'.json')
  189.                
  190.                 self.Library:Notify('Created theme')
  191.                 getgenv().Linoria.Options.ThemeManager_CustomThemeList:SetValues(self:ReloadCustomThemes())
  192.                 getgenv().Linoria.Options.ThemeManager_CustomThemeList:SetValue(nil)
  193.             end
  194.         end)
  195.  
  196.         groupbox:AddDivider()
  197.  
  198.         groupbox:AddDropdown('ThemeManager_CustomThemeList', { Text = 'Custom themes', Values = self:ReloadCustomThemes(), AllowNull = true, Default = 1 })
  199.         groupbox:AddButton('Load theme', function()
  200.             self:ApplyTheme(getgenv().Linoria.Options.ThemeManager_CustomThemeList.Value)
  201.         end)
  202.         groupbox:AddButton('Overwrite theme', function()
  203.             self:SaveCustomTheme(getgenv().Linoria.Options.ThemeManager_CustomThemeList.Value)
  204.             self.Library:Notify('Saved theme')
  205.         end):AddButton('Delete theme', function()
  206.             local name = getgenv().Linoria.Options.ThemeManager_CustomThemeList.Value
  207.  
  208.             local success, err = self:Delete(name)
  209.             if not success then
  210.                 return self.Library:Notify('Failed to delete theme: ' .. err)
  211.             end
  212.  
  213.             self.Library:Notify(string.format('Deleted theme %q', name))
  214.             getgenv().Linoria.Options.ThemeManager_CustomThemeList:SetValues(self:ReloadCustomThemes())
  215.             getgenv().Linoria.Options.ThemeManager_CustomThemeList:SetValue(nil)
  216.         end)
  217.         groupbox:AddButton('Refresh list', function()
  218.             getgenv().Linoria.Options.ThemeManager_CustomThemeList:SetValues(self:ReloadCustomThemes())
  219.             getgenv().Linoria.Options.ThemeManager_CustomThemeList:SetValue(nil)
  220.         end)
  221.         groupbox:AddButton('Set as default', function()
  222.             if getgenv().Linoria.Options.ThemeManager_CustomThemeList.Value ~= nil and getgenv().Linoria.Options.ThemeManager_CustomThemeList.Value ~= '' then
  223.                 self:SaveDefault(getgenv().Linoria.Options.ThemeManager_CustomThemeList.Value)
  224.                 self.Library:Notify(string.format('Set default theme to %q', getgenv().Linoria.Options.ThemeManager_CustomThemeList.Value))
  225.             end
  226.         end)
  227.         groupbox:AddButton('Reset default', function()
  228.             local success = pcall(delfile, self.Folder .. '/themes/default.txt')
  229.             if not success then
  230.                 return self.Library:Notify('Failed to reset default: delete file error')
  231.             end
  232.                
  233.             self.Library:Notify('Set default theme to nothing')
  234.             getgenv().Linoria.Options.ThemeManager_CustomThemeList:SetValues(self:ReloadCustomThemes())
  235.             getgenv().Linoria.Options.ThemeManager_CustomThemeList:SetValue(nil)
  236.         end)
  237.  
  238.         ThemeManager:LoadDefault()
  239.  
  240.         local function UpdateTheme()
  241.             self:ThemeUpdate()
  242.         end
  243.  
  244.         getgenv().Linoria.Options.BackgroundColor:OnChanged(UpdateTheme)
  245.         getgenv().Linoria.Options.MainColor:OnChanged(UpdateTheme)
  246.         getgenv().Linoria.Options.AccentColor:OnChanged(UpdateTheme)
  247.         getgenv().Linoria.Options.OutlineColor:OnChanged(UpdateTheme)
  248.         getgenv().Linoria.Options.FontColor:OnChanged(UpdateTheme)
  249.     end
  250.  
  251.     function ThemeManager:GetCustomTheme(file)
  252.         local path = self.Folder .. '/themes/' .. file
  253.         if not isfile(path) then
  254.             return nil
  255.         end
  256.  
  257.         local data = readfile(path)
  258.         local success, decoded = pcall(httpService.JSONDecode, httpService, data)
  259.        
  260.         if not success then
  261.             return nil
  262.         end
  263.  
  264.         return decoded
  265.     end
  266.  
  267.     function ThemeManager:SaveCustomTheme(file)
  268.         if file:gsub(' ', '') == '' then
  269.             return self.Library:Notify('Invalid file name for theme (empty)', 3)
  270.         end
  271.        
  272.         local theme = {}
  273.         local fields = { "FontColor", "MainColor", "AccentColor", "BackgroundColor", "OutlineColor", "VideoLink" }
  274.  
  275.         for _, field in next, fields do
  276.             if field == "VideoLink" then
  277.                 theme[field] = getgenv().Linoria.Options[field].Value
  278.             else
  279.                 theme[field] = getgenv().Linoria.Options[field].Value:ToHex()
  280.             end
  281.         end
  282.        
  283.         writefile(self.Folder .. '/themes/' .. file, httpService:JSONEncode(theme))
  284.     end
  285.  
  286.     function ThemeManager:ReloadCustomThemes()
  287.         local list = listfiles(self.Folder .. '/themes')
  288.  
  289.         local out = {}
  290.         for i = 1, #list do
  291.             local file = list[i]
  292.             if file:sub(-5) == '.json' then
  293.                 -- i hate this but it has to be done ...
  294.  
  295.                 local pos = file:find('.json', 1, true)
  296.                 local char = file:sub(pos, pos)
  297.  
  298.                 while char ~= '/' and char ~= '\\' and char ~= '' do
  299.                     pos = pos - 1
  300.                     char = file:sub(pos, pos)
  301.                 end
  302.  
  303.                 if char == '/' or char == '\\' then
  304.                     table.insert(out, file:sub(pos + 1))
  305.                 end
  306.             end
  307.         end
  308.  
  309.         return out
  310.     end
  311.  
  312.     function ThemeManager:SetLibrary(lib)
  313.         self.Library = lib
  314.     end
  315.  
  316.     function ThemeManager:BuildFolderTree()
  317.         local paths = {}
  318.  
  319.         -- build the entire tree if a path is like some-hub/phantom-forces
  320.         -- makefolder builds the entire tree on Synapse X but not other exploits
  321.  
  322.         local parts = self.Folder:split('/')
  323.         for idx = 1, #parts do
  324.             paths[#paths + 1] = table.concat(parts, '/', 1, idx)
  325.         end
  326.  
  327.         table.insert(paths, self.Folder .. '/themes')
  328.  
  329.         for i = 1, #paths do
  330.             local str = paths[i]
  331.             if not isfolder(str) then
  332.                 makefolder(str)
  333.             end
  334.         end
  335.     end
  336.  
  337.     function ThemeManager:SetFolder(folder)
  338.         self.Folder = folder
  339.         self:BuildFolderTree()
  340.     end
  341.  
  342.     function ThemeManager:CreateGroupBox(tab)
  343.         assert(self.Library, 'Must set ThemeManager.Library first!')
  344.         return tab:AddLeftGroupbox('Themes')
  345.     end
  346.  
  347.     function ThemeManager:ApplyToTab(tab)
  348.         assert(self.Library, 'Must set ThemeManager.Library first!')
  349.         local groupbox = self:CreateGroupBox(tab)
  350.         self:CreateThemeManager(groupbox)
  351.     end
  352.  
  353.     function ThemeManager:ApplyToGroupbox(groupbox)
  354.         assert(self.Library, 'Must set ThemeManager.Library first!')
  355.         self:CreateThemeManager(groupbox)
  356.     end
  357.  
  358.     ThemeManager:BuildFolderTree()
  359. end
  360.  
  361. return ThemeManager
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement