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: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
EXPO_PUBLIC_POSTHOG_API_KEY=
# Optional edition name
EXPO_PUBLIC_EDITION_NAME=
# Conference date in YYYY-MM-DD format
EXPO_PUBLIC_CONFERENCE_DATE=
6 changes: 5 additions & 1 deletion .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ jobs:
runs-on: ubuntu-latest
env:
EXPO_PUBLIC_POSTHOG_API_KEY: ${{ secrets.EXPO_PUBLIC_POSTHOG_API_KEY }}
EXPO_PUBLIC_CONFERENCE_DATE: ${{ vars.EXPO_PUBLIC_CONFERENCE_DATE }}
permissions:
contents: read
pull-requests: write
Expand All @@ -27,6 +28,9 @@ jobs:
echo "EXPO_PUBLIC_POSTHOG_API_KEY is not set"
exit 1
fi
- name: Print conference date
run: |
echo "Conference date: ${{ vars.EXPO_PUBLIC_CONFERENCE_DATE }}"
- name: Checkout repository
uses: actions/checkout@v3

Expand All @@ -48,4 +52,4 @@ jobs:
- name: Create preview
uses: expo/expo-github-action/preview@v8
with:
command: eas update --auto
command: eas update --auto --environment preview
14 changes: 13 additions & 1 deletion .github/workflows/update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:
env:
EXPO_PUBLIC_POSTHOG_API_KEY: ${{ secrets.EXPO_PUBLIC_POSTHOG_API_KEY }}
EXPO_PUBLIC_EDITION_NAME: ${{ vars.EXPO_PUBLIC_EDITION_NAME }}
EXPO_PUBLIC_CONFERENCE_DATE: ${{ vars.EXPO_PUBLIC_CONFERENCE_DATE }}
steps:
- name: Check for EXPO_TOKEN
run: |
Expand All @@ -28,6 +29,9 @@ jobs:
- name: Print edition name
run: |
echo "Edition name: ${{ vars.EXPO_PUBLIC_EDITION_NAME }}"
- name: Print conference date
run: |
echo "Conference date: ${{ vars.EXPO_PUBLIC_CONFERENCE_DATE }}"
- name: Checkout repository
uses: actions/checkout@v3

Expand All @@ -47,4 +51,12 @@ jobs:
run: yarn install

- name: Publish update
run: eas update --auto
run: |
if [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then
eas update --auto --environment production
elif [[ "${GITHUB_REF}" == "refs/heads/staging" ]]; then
eas update --auto --environment staging
else
echo "This workflow only runs EAS update on 'main' or 'staging' branches."
exit 0
fi
12 changes: 11 additions & 1 deletion __tests__/components/common/header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jest.mock('expo-router', () => ({
canGoBack: jest.fn().mockReturnValue(true),
goBack: jest.fn(),
}),
useSegments: jest.fn().mockReturnValue(['(tabs)', 'presentation', 'presentation-details']),
}));

beforeEach(() => {
Expand All @@ -31,12 +32,21 @@ it("should not render the back button if it can't go back", () => {
jest.spyOn(router, 'useNavigation').mockReturnValue({
canGoBack: jest.fn().mockReturnValue(false),
});

const { queryByTestId } = render(<Header />);
expect(queryByTestId('header-container')).toBeTruthy();
expect(queryByTestId('back-button')).toBeFalsy();
});

it('should not render the back button on stack root', () => {
jest.spyOn(router, 'useSegments').mockReturnValue(['(tabs)']);
const { queryByTestId } = render(
<Header>
<Title testID='title'>Root Screen</Title>
</Header>
);
expect(queryByTestId('back-button')).toBeFalsy();
});

it('should render the header with a corner', () => {
const { queryByTestId } = render(<Header corner={<View testID='corner' />} />);
expect(queryByTestId('corner')).toBeTruthy();
Expand Down
6 changes: 6 additions & 0 deletions app.config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { ConfigContext } from '@expo/config';
import { format } from 'date-fns';
import { config } from 'dotenv';
import * as env from 'env-var';
config();

const EXPO_PUBLIC_POSTHOG_API_KEY = env.get('EXPO_PUBLIC_POSTHOG_API_KEY').required().asString();
const EXPO_PUBLIC_EDITION_NAME = env.get('EXPO_PUBLIC_EDITION_NAME').default('').asString();
const EXPO_PUBLIC_CONFERENCE_DATE = env
.get('EXPO_PUBLIC_CONFERENCE_DATE')
.default(format(new Date(), 'yyyy-MM-dd'))
.asString();

export default ({ config }: ConfigContext) => {
return {
...config,
extra: {
posthogApiKey: EXPO_PUBLIC_POSTHOG_API_KEY,
editionName: EXPO_PUBLIC_EDITION_NAME,
conferenceDate: EXPO_PUBLIC_CONFERENCE_DATE,
...config.extra,
},
};
Expand Down
29 changes: 19 additions & 10 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
"name": "KonferenciApp",
"slug": "konferenciapp",
"scheme": "konferenciapp",
"version": "3.0.0",
"version": "4.0.0",
"orientation": "portrait",
"icon": "./assets/icon-light.png",
"newArchEnabled": true,
"userInterfaceStyle": "automatic",
"assetBundlePatterns": ["./assets"],
"assetBundlePatterns": [
"./assets"
],
"ios": {
"icon": {
"dark": "./assets/icon-dark.png",
Expand Down Expand Up @@ -54,11 +55,19 @@
"backgroundColor": "#000000"
}
}
]
],
"notification": {
"icon": "./assets/notification-icon.png",
"color": "#000000"
}
],
[
"expo-notifications",
{
"icon": "./assets/notification-icon.png",
"color": "#000000"
}
],
"expo-asset",
"expo-localization",
"expo-router",
"expo-image",
"expo-font"
]
}
}
}
31 changes: 21 additions & 10 deletions app/(tabs)/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ import { Screen } from '../../../components/base/screen';
import { ScrollContent } from '../../../components/base/scroll-content';
import { ErrorMessage } from '../../../components/common/error-message';
import { Header } from '../../../components/common/header';
import { HomePrText } from '../../../components/common/home-pr-text';
import { SectionTitle } from '../../../components/common/sectiontitle';
import { Separator } from '../../../components/common/separator';
import { StatusMessage } from '../../../components/common/status-message';
import { HomeNewsList } from '../../../components/news/layouts/home-news-list';
import { NewsItemSkeletonList } from '../../../components/news/layouts/news-item-skeleton-list';
import { HomePresentationList } from '../../../components/schedule/layouts/home-presentation-list';
import { PresentationItemSkeletonList } from '../../../components/schedule/layouts/presentation-item-skeleton-list';
import { useConference } from '../../../hooks/use-conference';
import { useNews } from '../../../hooks/use-news';
// import { useNews } from '../../../hooks/use-news';
import { isConferenceDay } from '../../../utils/date.utils';

export default function HomePage() {
const conference = useConference();
const news = useNews();
// const news = useNews();
const { t } = useTranslation();
const isArchive = useFeatureFlag('archive_mode');
const showPresentations = isConferenceDay();

return (
<Screen analyticsScreenName='home'>
Expand All @@ -36,16 +38,25 @@ export default function HomePage() {
</>
)}

<SectionTitle>{t('home.presentationTitle')}</SectionTitle>
{conference.isLoading && <PresentationItemSkeletonList className='mx-0' />}
{conference.isError && <ErrorMessage>{t('home.error')}</ErrorMessage>}
{!conference.isError && !conference.isLoading && (
<HomePresentationList presentations={conference.data?.presentations ?? []} />
{showPresentations && (
<>
<SectionTitle>{t('home.presentationTitle')}</SectionTitle>
{conference.isLoading && <PresentationItemSkeletonList className='mx-0' />}
{conference.isError && <ErrorMessage>{t('home.error')}</ErrorMessage>}
{!conference.isError && !conference.isLoading && (
<HomePresentationList presentations={conference.data?.presentations ?? []} />
)}
<Separator className='mb-5' />
</>
)}
<Separator className='mb-5' />

{!showPresentations && <HomePrText />}

{/*
<SectionTitle>{t('home.newsTitle')}</SectionTitle>
{news.isLoading && <NewsItemSkeletonList />}
{news.data && <HomeNewsList news={news.data.news} />}
*/}
</ScrollContent>
</Screen>
);
Expand Down
1 change: 1 addition & 0 deletions assets/Full.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/FullSand.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/adaptive-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/icon-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/icon-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/icon-tinted.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/notification-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/splash-icon-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/splash-icon-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 13 additions & 32 deletions components/base/logo.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,23 @@
import { Image } from 'expo-image';
import { useColorScheme } from 'react-native';
import Svg, { Path } from 'react-native-svg';

const logoWidth = 838;
const logoHeight = 134;
const logoWidth = 782.78;
const logoHeight = 310.59;

const logoResize = 2 / 7;
const logoResize = 70 / logoHeight;

export function Logo() {
const colorScheme = useColorScheme();
const fillColor = colorScheme === 'dark' ? 'white' : 'black';
const logoSource = colorScheme === 'dark' ? require('../../assets/FullSand.svg') : require('../../assets/Full.svg');

return (
<Svg width={logoWidth * logoResize} height={logoHeight * logoResize} viewBox='0 0 838 134'>
<Path
d='M239.904 133.665V0.426167C262.717 1.43276 286.663 -0.915961 309.345 0.426167C357.709 3.30683 375.2 48.4727 363.325 91.1671C347.88 146.694 283.394 131.423 239.904 133.657V133.665ZM280.436 99.6863H299.377C334.301 99.6863 335.768 34.3967 296.72 34.3967H280.436V99.6863Z'
fill='#EB0028'
/>
<Path
d='M232.594 0.426147V34.4049H162.151V51.0587H232.594V83.0325H162.151V99.6863H232.594V133.665H121.611V0.426147H232.594Z'
fill='#EB0028'
/>
<Path d='M114.968 0.426147V34.4049H77.7541V133.665H37.2144V34.4049H0V0.426147H114.968Z' fill='#EB0028' />
<Path
d='M625.007 4.4198L670.861 119.679L715.72 4.4198H732.999V133.665H721.034L721.694 19.085C720.741 18.9295 720.822 20.2062 720.545 20.91C716.78 30.4522 713.821 40.69 710.064 50.3795C699.273 78.2205 687.145 105.734 675.857 133.338L664.878 133.002L619.693 19.0686L620.027 133.665H608.062V5.4264L609.057 4.42798H625.007V4.4198Z'
fill={fillColor}
/>
<Path
d='M498.409 5.42638C498.995 4.47707 499.737 4.50981 500.699 4.39524C511.816 3.08584 545.526 3.60142 555.974 6.34296C575.918 11.5805 585.756 33.161 577.499 52.0735C573.823 60.4782 568.159 62.9006 560.481 66.3213C559.683 66.6732 559.283 66.0104 559.544 67.7126C568.322 68.0072 576.994 74.8815 581.102 82.4105C593.319 104.785 578.054 133.665 551.899 133.665H498.4V5.42638H498.409ZM511.042 63.0479H546.593C550.783 63.0479 558.533 59.0542 561.565 56.0753C575.185 42.7032 567.018 15.7542 547.262 15.7542H511.042V63.056V63.0479ZM511.042 122.339H552.576C553.969 122.339 560.025 120.154 561.574 119.368C578.836 110.62 576.065 85.5121 560.009 76.9192C558.688 76.2154 552.29 73.7112 551.247 73.7112H511.042V122.347V122.339Z'
fill={fillColor}
/>
<Path
d='M401.054 0.426147L412.024 20.4108L424.307 0.426147H453.216L426.638 40.7309L454.544 82.3696H424.975L413.01 62.3768C412.081 62.1722 411.894 62.9251 411.47 63.498C407.476 68.7846 404.232 76.6083 400.728 82.3696H370.824L398.723 40.7309L371.484 0.426147H401.054Z'
fill='#EB0028'
/>
<Path
d='M837.331 15.746H774.199V63.0479H832.343L833.232 64.1527C833.052 67.3443 834.332 71.8372 832.343 74.3741H774.199V122.339H838V133.665H762.242V4.4198H836.337L837.331 5.41821V15.746Z'
fill={fillColor}
/>
</Svg>
<Image
source={logoSource}
style={{
width: logoWidth * logoResize,
height: logoHeight * logoResize,
}}
contentFit='contain'
/>
);
}
6 changes: 4 additions & 2 deletions components/common/header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Feather } from '@expo/vector-icons';
import { useNavigation } from 'expo-router';
import { useNavigation, useSegments } from 'expo-router';
import { Pressable, View, ViewProps } from 'react-native';

import { extendedColors } from '../../theme/extendedColors';
Expand All @@ -12,7 +12,9 @@ interface HeaderProps extends ViewProps {

export function Header({ children, className, corner, ...props }: HeaderProps) {
const navigation = useNavigation();
const showBackButton = navigation.canGoBack();
const segments = useSegments();
const isStackRoot = segments.length <= 2;
const showBackButton = navigation.canGoBack() && !isStackRoot;
return (
<View testID='header-container' className={cn('space-y-5 mx-5', className)} {...props}>
{(showBackButton || corner) && (
Expand Down
27 changes: 27 additions & 0 deletions components/common/home-pr-text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Linking, Text, View } from 'react-native';

import { StyledButton } from './styled-button';

export function HomePrText() {
const { t } = useTranslation();

return (
<View className='flex-1 items-center justify-center p-6 mt-10 gap-6'>
<Text className='text-center text-lg font-medium opacity-80 text-black dark:text-white'>{t('home.prText')}</Text>
<View className='gap-2 items-center justify-center w-full'>
<Text className='text-center text-base opacity-70 text-black dark:text-white'>
{t('home.prRegistrationPre')}
</Text>
<StyledButton
variant='primary'
className='w-full'
onPress={() => Linking.openURL(t('home.prRegistrationLink'))}
>
{t('home.prRegistrationBtn')}
</StyledButton>
</View>
</View>
);
}
6 changes: 3 additions & 3 deletions components/schedule/elements/favorite-button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AntDesign } from '@expo/vector-icons';
import { FontAwesome } from '@expo/vector-icons';
import { useMemo } from 'react';
import { Pressable } from 'react-native';

Expand All @@ -25,8 +25,8 @@ export function FavoriteButton({ presentation }: FavoriteButtonProps) {

return (
<Pressable testID='favorite-button' onPress={onPress} className='mr-3'>
<AntDesign
name={isFavorite ? 'star' : 'staro'}
<FontAwesome
name={isFavorite ? 'star' : 'star-o'}
color={isFavorite ? extendedColors.primary['500'] : extendedColors.background['500']}
size={30}
/>
Expand Down
20 changes: 13 additions & 7 deletions components/schedule/elements/presentation-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useFavoritePresentations } from '../../../contexts/favorite-presentatio
import { ConferenceService } from '../../../services/conference.service';
import { PresentationDto } from '../../../types/conference-api.type';
import { cn } from '../../../utils/common.utils';
import { isConferenceDay } from '../../../utils/date.utils';
import { isPresentationPast } from '../../../utils/presentation.utils';
import { ItemCard } from '../../base/item-card';
import { StyledText } from '../../base/text';
Expand All @@ -21,7 +22,8 @@ export function PresentationItem({ presentation, className, ...props }: Presenta
const { isFavoritePresentation } = useFavoritePresentations();
const isArchive = useFeatureFlag('archive_mode');
const router = useNavigation<NativeStackNavigationProp<{ 'presentation-details': { id: string } }>>();
const isPast = isPresentationPast(presentation) && !isArchive;
const isConference = isConferenceDay();
const isPast = isPresentationPast(presentation) && !isArchive && isConference;
const isFavorite = isFavoritePresentation(presentation.slug);
const startTime = ConferenceService.getFormattedTimestamp(presentation.startTime);
const endTime = ConferenceService.getFormattedTimestamp(presentation.endTime);
Expand All @@ -40,18 +42,22 @@ export function PresentationItem({ presentation, className, ...props }: Presenta
onPress={onPress}
{...props}
>
<Image source={{ uri: presentation.presenter.pictureUrl }} className='rounded-full h-14 w-14' />
{presentation.presenter && (
<Image source={{ uri: presentation.presenter.pictureUrl }} className='rounded-full h-14 w-14' />
)}
<View className='flex-col gap-2 flex-1 mx-2'>
<StyledText className='text-xl' numberOfLines={1}>
{presentation.title}
</StyledText>
<View className='flex-row overflow-hidden'>
<StyledText className='text-background-400 dark:text-background-400 flex-shrink' numberOfLines={1}>
{presentation.presenter.name}
</StyledText>
{presentation.presenter && (
<StyledText className='text-background-400 dark:text-background-400 flex-shrink' numberOfLines={1}>
{presentation.presenter.name}
</StyledText>
)}
<StyledText className='text-background-400 dark:text-background-400' numberOfLines={1}>
{' '}
{startTime} - {endTime}
{presentation.presenter && ' • '}
{startTime} - {endTime}
</StyledText>
</View>
</View>
Expand Down
Loading
Loading