Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"react-native-version-info": "^1.1.1",
"react-native-zeroconf": "^0.13.6",
"react-refresh": "^0.11.0",
"styled-components": "^5.3.3",
"styled-components": "^5.3.5",
"ts-mixer": "^6.0.0",
"yup": "^0.32.11"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,17 @@ export function CpuUsageWidget(): JSX.Element {
// 0 means no refresh
if (dashboard.cpuRefresh !== 0) {
interval = setInterval(() => {
console.log('refreshing...');
fetchUsage();
}, dashboard.cpuRefresh);
}

return () => (interval ? clearInterval(interval) : undefined);
return () => {
if (interval) {
console.log('Clearing inv');
clearInterval(interval);
}
};
}, [instance, dashboard.cpuRefresh]);

if (!cpuUsage) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Typography } from '@atoms/Typography/Typography';
import styled from 'styled-components/native';

export const FeatureNotInstalled = styled.View`
display: flex;
justify-content: center;
align-items: center;
`;

export const Text = styled(Typography)`
color: ${({ theme }) => theme['400']};
text-align: center;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { View } from 'react-native';
import { Icon } from '@atoms/Icon/Icon';
import { TypographyVariants } from '@atoms/Typography/Typography';
import { useTheme } from 'styled-components';
import * as S from './FeatureNotInstalled.styled';

export interface FeatureNotInstalledProps {
featureName: string;
installationDescription: string;
}

export function FeatureNotInstalled({ featureName, installationDescription }: FeatureNotInstalledProps): JSX.Element {
const theme = useTheme();

return (
<S.FeatureNotInstalled>
<Icon name={'help-circle'} size={150} color={theme[700]} />
<View>
<S.Text variant={TypographyVariants.H3}>You don't have {featureName} installed.</S.Text>
<S.Text variant={TypographyVariants.Paragraph}>{installationDescription}</S.Text>
</View>
</S.FeatureNotInstalled>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Box } from '@atoms/Box/Box';
import styled from 'styled-components/native';

export const UserScriptCard = styled(Box)`
display: flex;
flex-direction: row;
align-items: center;
`;
16 changes: 16 additions & 0 deletions src/components/molecules/UserScriptCard/UserScriptCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { Typography, TypographyVariants } from '@atoms/Typography/Typography';
import type { UserScript } from '@ridenui/unraid/dist/modules/unraid/extensions/userscripts/user-script';
import * as S from './UserScriptCard.styled';

export interface UserScriptCardProps {
script: UserScript;
}

export function UserScriptCard({ script }: UserScriptCardProps): JSX.Element {
return (
<S.UserScriptCard>
<Typography variant={TypographyVariants.Paragraph}>{script.name}</Typography>
</S.UserScriptCard>
);
}
21 changes: 20 additions & 1 deletion src/contexts/Server.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { log } from '@helpers/Logger';
import type { Container } from '@ridenui/unraid/dist/modules/docker/container';
import type { IDiskFreeReturn, IInfoResult } from '@ridenui/unraid/dist/modules/system/extensions';
import type { IdentConfig, RichNotification } from '@ridenui/unraid/dist/modules/unraid/extensions';
import type { UserScript } from '@ridenui/unraid/dist/modules/unraid/extensions/userscripts/user-script';
import { parse } from 'date-fns';
import { DEBUG } from '../constants';
import { useUnraid } from './Unraid.context';
Expand All @@ -21,7 +22,7 @@ type ServerProviderProps = {
children: ReactNode;
};

export type ReloadableProperties = 'notifications' | 'docker:containers';
export type ReloadableProperties = 'notifications' | 'docker:containers' | 'userscripts:all';

export type ServerProviderValue = {
hostname: string;
Expand All @@ -38,6 +39,10 @@ export type ServerProviderValue = {
reloadProperty: (property: ReloadableProperties) => void;
resetProperties: () => void;
isReloading: boolean;
userScripts: {
installed: boolean;
scripts: UserScript[];
};
};

const initialServerState: ServerProviderValue = {
Expand All @@ -50,6 +55,10 @@ const initialServerState: ServerProviderValue = {
docker: {
containers: [],
},
userScripts: {
installed: false,
scripts: [],
},
reloadProperties: () => {},
reloadProperty: () => {},
resetProperties: () => {},
Expand All @@ -69,6 +78,8 @@ export function ServerProvider({ children }: ServerProviderProps): JSX.Element {
const [diskUsage, setDiskUsage] = useState<IDiskFreeReturn[] | null>(null);
const [notifications, setNotifications] = useState<RichNotification[]>([]);
const [containers, setContainers] = useState<Container[]>([]);
const [hasUserScripts, setHasUserScripts] = useState(false);
const [userScriptList, setUserScriptList] = useState<UserScript[]>([]);
const { instance } = useUnraid();

const reloadProperties = useCallback(async () => {
Expand All @@ -83,6 +94,8 @@ export function ServerProvider({ children }: ServerProviderProps): JSX.Element {
[async () => setDiskUsage(await instance.system.diskfree()), 'diskfree'],
[async () => setNotifications(await instance.unraid.getNotifications()), 'notifications'],
[async () => setContainers(await instance.docker.list()), 'containers'],
[async () => setHasUserScripts(await instance.unraid.hasUserScriptsInstalled()), 'hasUserScripts'],
[async () => setUserScriptList(await instance.unraid.getUserScripts()), 'getUserScripts'],
[
async () => {
const { raw } = await instance.system.uptime();
Expand Down Expand Up @@ -130,6 +143,8 @@ export function ServerProvider({ children }: ServerProviderProps): JSX.Element {
setDiskUsage(null);
setNotifications([]);
setContainers([]);
setHasUserScripts(false);
setUserScriptList([]);
}, []);

const reloadProperty = useCallback(
Expand Down Expand Up @@ -181,6 +196,10 @@ export function ServerProvider({ children }: ServerProviderProps): JSX.Element {
docker: {
containers,
},
userScripts: {
installed: hasUserScripts,
scripts: userScriptList,
},
}}
>
{children}
Expand Down
1 change: 1 addition & 0 deletions src/navigation/DashboardStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Icon } from '@atoms/Icon/Icon';
import { createStackNavigator } from '@react-navigation/stack';
import { useTheme } from 'styled-components/native';
import { useServer } from '../contexts/Server.context';
import { useUnraid } from '../contexts/Unraid.context';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [eslint] <@typescript-eslint/no-unused-vars> reported by reviewdog 🐶
'useUnraid' is defined but never used.

import { DashboardScreen } from '../screens/dashboard/Dashboard.screen';
import { NotificationsScreen } from '../screens/notifications/Notifications';

Expand Down
3 changes: 3 additions & 0 deletions src/navigation/SideMenuStack.helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export function getDrawerIcon(route: string, focused: boolean, color: string, si
case 'Logout':
icon = 'log-out';
break;
case 'UserScripts':
icon = 'file-text';
break;
default:
icon = 'help-circle';
}
Expand Down
7 changes: 7 additions & 0 deletions src/navigation/SideMenuStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import { createDrawerNavigator } from '@react-navigation/drawer';
import { getNavigationStyle } from '@styles/NavigationStyle';
import { useTheme } from 'styled-components/native';
import { DEBUG } from '../constants';
import { useServer } from '../contexts/Server.context';
import { DebugScreen } from '../screens/debug/Debug.screen';
import { DockerContainerListScreen } from '../screens/dockercontainerlist/DockerContainerList';
import { SettingsScreen } from '../screens/settings/Settings.screen';
import { UserScriptsScreen } from '../screens/userscripts/UserScripts';
import { Dashboard } from './DashboardStack';
import { getDrawerIcon } from './SideMenuStack.helpers';

export type SideMenuStackParamList = {
DashboardStack: undefined;
DockerContainerList: undefined;
UserScripts: undefined;
Settings: undefined;
Debug: undefined;
};
Expand All @@ -25,6 +28,7 @@ export const SideMenuStack = createDrawerNavigator<SideMenuStackParamList>();

export function SideMenuNavigation() {
const theme = useTheme();
const { userScripts } = useServer();

return (
<SideMenuStack.Navigator
Expand All @@ -49,6 +53,9 @@ export function SideMenuNavigation() {
component={DockerContainerListScreen}
options={{ title: 'Docker' }}
/>
{userScripts.installed && (
<SideMenuStack.Screen name={'UserScripts'} component={UserScriptsScreen} options={{ title: 'User Scripts' }} />
)}
<SideMenuStack.Screen name={'Settings'} component={SettingsScreen} />
{DEBUG && <SideMenuStack.Screen name={'Debug'} component={DebugScreen} />}
</SideMenuStack.Navigator>
Expand Down
7 changes: 7 additions & 0 deletions src/screens/userscripts/UserScripts.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import styled from 'styled-components/native';

export const Container = styled.SafeAreaView`
background: ${({ theme }) => theme['600']};
flex: 1;
flex-direction: column;
`;
38 changes: 38 additions & 0 deletions src/screens/userscripts/UserScripts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import { FlatList, RefreshControl } from 'react-native';
import { FeatureNotInstalled } from '@molecules/FeatureNotInstalled/FeatureNotInstalled';
import { ListEmptyComponent } from '@molecules/ListEmptyComponent/ListEmptyComponent';
import { UserScriptCard } from '@molecules/UserScriptCard/UserScriptCard';
import { useServer } from '../../contexts/Server.context';
import * as S from './UserScripts.styled';

/**
* Lists all your userscripts
*/
export function UserScriptsScreen(): JSX.Element {
const { userScripts, isReloading, reloadProperty } = useServer();

if (!userScripts.installed) {
return (
<S.Container>
<FeatureNotInstalled
featureName={'User Scripts'}
installationDescription={'Install it via Community Applications'}
/>
</S.Container>
);
}

return (
<S.Container>
<FlatList
refreshing={isReloading}
onRefresh={() => reloadProperty('userscripts:all')}
refreshControl={<RefreshControl refreshing={isReloading} onRefresh={() => reloadProperty('userscripts:all')} />}
data={userScripts.scripts}
renderItem={(item) => <UserScriptCard script={item} />}
ListEmptyComponent={<ListEmptyComponent />}
/>
</S.Container>
);
}
2 changes: 2 additions & 0 deletions src/unraid/unraid-ssh-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export class ReactNativeExecutor extends Executor<SSHConfig> {
command = command.command;
}

command = command.replace('\n', '');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [eslint] <no-param-reassign> reported by reviewdog 🐶
Assignment to function parameter 'command'.


if (DEBUG) {
log.debug({ command, execute: true });
}
Expand Down
28 changes: 14 additions & 14 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1062,17 +1062,17 @@
dependencies:
"@types/hammerjs" "^2.0.36"

"@emotion/is-prop-valid@^0.8.8":
version "0.8.8"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
"@emotion/is-prop-valid@^1.1.0":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.1.2.tgz#34ad6e98e871aa6f7a20469b602911b8b11b3a95"
integrity sha512-3QnhqeL+WW88YjYbQL5gUIkthuMw7a0NGbZ7wfFVk2kg/CK5w8w5FFa0RzWjyY1+sujN0NWbtSHH6OJmWHtJpQ==
dependencies:
"@emotion/memoize" "0.7.4"
"@emotion/memoize" "^0.7.4"

"@emotion/memoize@0.7.4":
version "0.7.4"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
"@emotion/memoize@^0.7.4":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50"
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==

"@emotion/stylis@^0.8.4":
version "0.8.5"
Expand Down Expand Up @@ -9077,14 +9077,14 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==

styled-components@^5.3.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.3.tgz#312a3d9a549f4708f0fb0edc829eb34bde032743"
integrity sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==
styled-components@^5.3.5:
version "5.3.5"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.5.tgz#a750a398d01f1ca73af16a241dec3da6deae5ec4"
integrity sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/traverse" "^7.4.5"
"@emotion/is-prop-valid" "^0.8.8"
"@emotion/is-prop-valid" "^1.1.0"
"@emotion/stylis" "^0.8.4"
"@emotion/unitless" "^0.7.4"
babel-plugin-styled-components ">= 1.12.0"
Expand Down