mirror of
https://github.com/owncast/owncast.git
synced 2024-11-22 04:40:37 +03:00
Hide disabled features (#2473)
* Hide/show on notify and fediverse feature disable/enable * Update browser tests to enable features for testing * Hide/show features in mobile action menu * Do not show fediauth option if fediverse features are not enabled. * Force showing tabs when in Storybook
This commit is contained in:
parent
0eba1685b3
commit
533d33847c
8 changed files with 110 additions and 70 deletions
|
@ -9,8 +9,8 @@ describe(`Basic tests`, () => {
|
|||
// Offline banner
|
||||
it('Has correct offline banner values', () => {
|
||||
cy.contains(
|
||||
'This stream is offline. Be notified the next time New Owncast Server goes live.'
|
||||
).should('be.visible');
|
||||
'This stream is offline. You can be notified the next time New Owncast Server goes live or follow streamer@testing.biz on the Fediverse.'
|
||||
).should('exist');
|
||||
});
|
||||
|
||||
// Verify the tags show up
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { setup } from '../../support/setup.js';
|
||||
import fetchData from '../../support/fetchData.js';
|
||||
|
||||
setup();
|
||||
|
||||
|
@ -81,45 +82,3 @@ describe(`Live tests`, () => {
|
|||
cy.visit('http://localhost:8080');
|
||||
});
|
||||
});
|
||||
|
||||
async function fetchData(url, options) {
|
||||
const ADMIN_USERNAME = 'admin';
|
||||
const ADMIN_STREAMKEY = 'abc123';
|
||||
|
||||
const { data, method = 'GET', auth = true } = options || {};
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const requestOptions = {
|
||||
method,
|
||||
};
|
||||
|
||||
if (data) {
|
||||
requestOptions.body = JSON.stringify(data);
|
||||
}
|
||||
|
||||
if (auth && ADMIN_USERNAME && ADMIN_STREAMKEY) {
|
||||
const encoded = btoa(`${ADMIN_USERNAME}:${ADMIN_STREAMKEY}`);
|
||||
requestOptions.headers = {
|
||||
Authorization: `Basic ${encoded}`,
|
||||
};
|
||||
requestOptions.mode = 'cors';
|
||||
requestOptions.credentials = 'include';
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(url, requestOptions);
|
||||
const json = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
const message =
|
||||
json.message || `An error has occurred: ${response.status}`;
|
||||
throw new Error(message);
|
||||
}
|
||||
return json;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return error;
|
||||
// console.log(error)
|
||||
// throw new Error(error)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
|
@ -15,6 +15,21 @@
|
|||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
||||
import fetchData from './fetchData.js';
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
|
||||
// Put Owncast in a state where it's ready to be tested.
|
||||
|
||||
// Set server URL
|
||||
fetchData('http://localhost:8080/api/admin/config/serverurl', {
|
||||
method: 'POST',
|
||||
data: { value: 'https://testing.biz' },
|
||||
});
|
||||
|
||||
// Enable Fediverse features.
|
||||
fetchData('http://localhost:8080/api/admin/config/federation/enable', {
|
||||
method: 'POST',
|
||||
data: { value: true },
|
||||
});
|
||||
|
|
43
test/automated/browser/cypress/support/fetchData.js
Normal file
43
test/automated/browser/cypress/support/fetchData.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
async function fetchData(url, options) {
|
||||
const ADMIN_USERNAME = 'admin';
|
||||
const ADMIN_STREAMKEY = 'abc123';
|
||||
|
||||
const { data, method = 'GET', auth = true } = options || {};
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const requestOptions = {
|
||||
method,
|
||||
};
|
||||
|
||||
if (data) {
|
||||
requestOptions.body = JSON.stringify(data);
|
||||
}
|
||||
|
||||
if (auth && ADMIN_USERNAME && ADMIN_STREAMKEY) {
|
||||
const encoded = btoa(`${ADMIN_USERNAME}:${ADMIN_STREAMKEY}`);
|
||||
requestOptions.headers = {
|
||||
Authorization: `Basic ${encoded}`,
|
||||
};
|
||||
requestOptions.mode = 'cors';
|
||||
requestOptions.credentials = 'include';
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(url, requestOptions);
|
||||
const json = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
const message =
|
||||
json.message || `An error has occurred: ${response.status}`;
|
||||
throw new Error(message);
|
||||
}
|
||||
return json;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return error;
|
||||
// console.log(error)
|
||||
// throw new Error(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default fetchData;
|
|
@ -21,7 +21,7 @@ const Example = () => {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<AuthModal />
|
||||
<AuthModal forceTabs />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,18 +12,26 @@ import {
|
|||
currentUserAtom,
|
||||
chatAuthenticatedAtom,
|
||||
accessTokenAtom,
|
||||
clientConfigStateAtom,
|
||||
} from '../../stores/ClientConfigStore';
|
||||
import { ClientConfig } from '../../../interfaces/client-config.model';
|
||||
|
||||
export const AuthModal: FC = () => {
|
||||
export type AuthModalProps = {
|
||||
forceTabs?: boolean;
|
||||
};
|
||||
|
||||
export const AuthModal: FC<AuthModalProps> = ({ forceTabs }) => {
|
||||
const authenticated = useRecoilValue<boolean>(chatAuthenticatedAtom);
|
||||
const accessToken = useRecoilValue<string>(accessTokenAtom);
|
||||
const currentUser = useRecoilValue(currentUserAtom);
|
||||
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
|
||||
|
||||
if (!currentUser) {
|
||||
return null;
|
||||
}
|
||||
const { displayName } = currentUser;
|
||||
|
||||
const federationEnabled = true;
|
||||
const { federation } = clientConfig;
|
||||
const { enabled: fediverseEnabled } = federation;
|
||||
|
||||
const indieAuthTabTitle = (
|
||||
<span className={styles.tabContent}>
|
||||
|
@ -67,7 +75,7 @@ export const AuthModal: FC = () => {
|
|||
items={items}
|
||||
type="card"
|
||||
size="small"
|
||||
renderTabBar={federationEnabled ? null : () => null}
|
||||
renderTabBar={fediverseEnabled || forceTabs ? null : () => null}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Layout, Tabs, Skeleton } from 'antd';
|
|||
import { FC, useEffect, useState } from 'react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { LOCAL_STORAGE_KEYS, getLocalStorage, setLocalStorage } from '../../../utils/localStorage';
|
||||
import isPushNotificationSupported from '../../../utils/browserPushNotifications';
|
||||
|
||||
import {
|
||||
clientConfigStateAtom,
|
||||
|
@ -66,16 +67,17 @@ const DesktopContent = ({
|
|||
socialHandles,
|
||||
extraPageContent,
|
||||
setShowFollowModal,
|
||||
supportFediverseFeatures,
|
||||
}) => {
|
||||
const aboutTabContent = <CustomPageContent content={extraPageContent} />;
|
||||
const followersTabContent = (
|
||||
<FollowerCollection name={name} onFollowButtonClick={() => setShowFollowModal(true)} />
|
||||
);
|
||||
|
||||
const items = [
|
||||
{ label: 'About', key: '2', children: aboutTabContent },
|
||||
{ label: 'Followers', key: '3', children: followersTabContent },
|
||||
];
|
||||
const items = [{ label: 'About', key: '2', children: aboutTabContent }];
|
||||
if (supportFediverseFeatures) {
|
||||
items.push({ label: 'Followers', key: '3', children: followersTabContent });
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -91,7 +93,7 @@ const DesktopContent = ({
|
|||
</div>
|
||||
|
||||
<div className={styles.lowerSection}>
|
||||
<Tabs defaultActiveKey="0" items={items} />
|
||||
{items.length > 1 ? <Tabs defaultActiveKey="0" items={items} /> : aboutTabContent}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -111,6 +113,8 @@ const MobileContent = ({
|
|||
setExternalActionToDisplay,
|
||||
setShowNotifyPopup,
|
||||
setShowFollowModal,
|
||||
supportFediverseFeatures,
|
||||
supportsBrowserNotifications,
|
||||
}) => {
|
||||
if (!currentUser) {
|
||||
return null;
|
||||
|
@ -153,8 +157,8 @@ const MobileContent = ({
|
|||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'start' }}>
|
||||
<DefaultTabBar {...props} style={{ width: '85%' }} />
|
||||
<ActionButtonMenu
|
||||
showFollowItem
|
||||
showNotifyItem
|
||||
showFollowItem={supportFediverseFeatures}
|
||||
showNotifyItem={supportsBrowserNotifications}
|
||||
actions={actions}
|
||||
externalActionSelected={setExternalActionToDisplay}
|
||||
notifyItemSelected={() => setShowNotifyPopup(true)}
|
||||
|
@ -217,11 +221,14 @@ export const Content: FC = () => {
|
|||
const [showNotifyReminder, setShowNotifyReminder] = useState(false);
|
||||
const [showNotifyModal, setShowNotifyModal] = useState(false);
|
||||
const [showFollowModal, setShowFollowModal] = useState(false);
|
||||
const { account: fediverseAccount } = federation;
|
||||
const { account: fediverseAccount, enabled: fediverseEnabled } = federation;
|
||||
const { browser: browserNotifications } = notifications;
|
||||
const { enabled: browserNotificationsEnabled } = browserNotifications;
|
||||
const [externalActionToDisplay, setExternalActionToDisplay] = useState<ExternalAction>(null);
|
||||
|
||||
const [supportsBrowserNotifications, setSupportsBrowserNotifications] = useState(false);
|
||||
const supportFediverseFeatures = fediverseEnabled;
|
||||
|
||||
const externalActionSelected = (action: ExternalAction) => {
|
||||
const { openExternally, url } = action;
|
||||
if (openExternally) {
|
||||
|
@ -277,6 +284,12 @@ export const Content: FC = () => {
|
|||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// isPushNotificationSupported relies on `navigator` so that needs to be
|
||||
// fired from this useEffect.
|
||||
setSupportsBrowserNotifications(isPushNotificationSupported() && browserNotificationsEnabled);
|
||||
}, [browserNotificationsEnabled]);
|
||||
|
||||
const showChat = !chatDisabled && isChatAvailable && isChatVisible;
|
||||
|
||||
return (
|
||||
|
@ -312,14 +325,18 @@ export const Content: FC = () => {
|
|||
{!isMobile && (
|
||||
<ActionButtonRow>
|
||||
{externalActionButtons}
|
||||
<FollowButton size="small" onClick={() => setShowFollowModal(true)} />
|
||||
<NotifyReminderPopup
|
||||
open={showNotifyReminder}
|
||||
notificationClicked={() => setShowNotifyModal(true)}
|
||||
notificationClosed={() => disableNotifyReminderPopup()}
|
||||
>
|
||||
<NotifyButton onClick={() => setShowNotifyModal(true)} />
|
||||
</NotifyReminderPopup>
|
||||
{supportFediverseFeatures && (
|
||||
<FollowButton size="small" onClick={() => setShowFollowModal(true)} />
|
||||
)}
|
||||
{supportsBrowserNotifications && (
|
||||
<NotifyReminderPopup
|
||||
open={showNotifyReminder}
|
||||
notificationClicked={() => setShowNotifyModal(true)}
|
||||
notificationClosed={() => disableNotifyReminderPopup()}
|
||||
>
|
||||
<NotifyButton onClick={() => setShowNotifyModal(true)} />
|
||||
</NotifyReminderPopup>
|
||||
)}
|
||||
</ActionButtonRow>
|
||||
)}
|
||||
|
||||
|
@ -348,6 +365,8 @@ export const Content: FC = () => {
|
|||
setExternalActionToDisplay={externalActionSelected}
|
||||
setShowNotifyPopup={setShowNotifyModal}
|
||||
setShowFollowModal={setShowFollowModal}
|
||||
supportFediverseFeatures={supportFediverseFeatures}
|
||||
supportsBrowserNotifications={supportsBrowserNotifications}
|
||||
/>
|
||||
) : (
|
||||
<DesktopContent
|
||||
|
@ -358,6 +377,7 @@ export const Content: FC = () => {
|
|||
socialHandles={socialHandles}
|
||||
extraPageContent={extraPageContent}
|
||||
setShowFollowModal={setShowFollowModal}
|
||||
supportFediverseFeatures={supportFediverseFeatures}
|
||||
/>
|
||||
)}
|
||||
<Footer version={version} />
|
||||
|
|
Loading…
Reference in a new issue