Skip to content

Commit

Permalink
Merge pull request #2146 from amvanbaren/feature/issue-773
Browse files Browse the repository at this point in the history
Show Adopters of Open VSX on the Website
  • Loading branch information
amvanbaren authored Oct 16, 2023
2 parents b4a73b6 + 30ea13b commit be987ba
Show file tree
Hide file tree
Showing 7 changed files with 298 additions and 37 deletions.
2 changes: 1 addition & 1 deletion configuration/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ ovsx:
storage:
primary-service: azure-blob
webui:
frontendRoutes: "/extension/**,/namespace/**,/user-settings/**,/admin-dashboard/**,/about,/publisher-agreement-*,/terms-of-use,/members"
frontendRoutes: "/extension/**,/namespace/**,/user-settings/**,/admin-dashboard/**,/about,/publisher-agreement-*,/terms-of-use,/members,/adopters"
eclipse:
# TODO change back to https://api.eclipse.org/ for release.
base-url: https://api-staging.eclipse.org/
Expand Down
2 changes: 1 addition & 1 deletion website/dev/mock-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
NamespaceMembershipList, AdminService, PublisherInfo, NewReview, ExtensionFilter, UrlString, MembershipRole
} from "openvsx-webui";

const avatarUrl = 'https://upload.wikimedia.org/wikipedia/commons/1/19/Spongebob_Squarepants_as_a_balloon.jpg';
const avatarUrl = 'https://upload.wikimedia.org/wikipedia/commons/9/99/Avatar_cupcake.png';

export class MockRegistryService extends ExtensionRegistryService {

Expand Down
25 changes: 19 additions & 6 deletions website/src/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
********************************************************************************/

import * as React from 'react';
import { Link, Typography, Container } from '@mui/material';
import { Link, Typography, Container, List, ListItem, ListItemText } from '@mui/material';
import { styled, Theme } from '@mui/material/styles';

const Heading = styled(Typography)(({ theme }: { theme: Theme }) => ({
Expand Down Expand Up @@ -58,11 +58,24 @@ const About = () => {
</li>
</RepositoryList>

<Heading variant='h5'>Publishing Extensions</Heading>
<Paragraph variant='body1'>
The publishing process is described in
the <Link color='secondary' underline='hover' href='https://github.com/eclipse/openvsx/wiki/Publishing-Extensions#how-to-publish-an-extension'>openvsx Wiki</Link>.
</Paragraph>
<Heading variant='h5'>Resources</Heading>
<List>
<ListItem>
<ListItemText>
The publishing process is described in the <Link color='secondary' underline='hover' href='https://github.com/eclipse/openvsx/wiki/Publishing-Extensions#how-to-publish-an-extension'>openvsx Wiki</Link>.
</ListItemText>
</ListItem>
<ListItem>
<ListItemText>
The <Link color='secondary' underline='hover' href='https://www.eclipse.org/legal/open-vsx-registry-faq/'>FAQ</Link> section explains what you can and cannot do as a user of our service.
</ListItemText>
</ListItem>
<ListItem>
<ListItemText>
Get involved in the <Link color='secondary' underline='hover' href='https://gitter.im/eclipse/openvsx'>community</Link>.
</ListItemText>
</ListItem>
</List>
</Container>;
}

Expand Down
34 changes: 34 additions & 0 deletions website/src/adopters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";
import { Container, Typography, Box, Button } from "@mui/material";
import { styled, Theme } from '@mui/material/styles';
import AdoptersList from "./components/adopters-list";

const Heading = styled(Typography)(({ theme }: { theme: Theme }) => ({
marginTop: theme.spacing(4),
marginBottom: theme.spacing(2)
}));

const Adopters = () => {
return (
<Container maxWidth='md'>
<Heading variant='h4'>
Adopters
</Heading>
<Typography>
Our open source projects drive innovation across a broad spectrum of industries and on both private and public clouds — enabling organizations of all shapes and sizes to accelerate cloud native development with world-class tools.
</Typography>
<AdoptersList/>
<Box mt={4} textAlign='center'>
<Button
variant='contained'
color='secondary'
href='https://ecdtools.eclipse.org/adopters/get-listed/'
>
Get Listed
</Button>
</Box>
</Container>
);
}

export default Adopters;
163 changes: 163 additions & 0 deletions website/src/components/adopters-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/********************************************************************************
* Copyright (c) 2023 TypeFox and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/

import React, { FunctionComponent, useState, useEffect, useContext } from 'react';
import { CircularProgress, Grid, Box, Link, Typography } from '@mui/material';
import { styled, Theme } from '@mui/material/styles';
import { MainContext } from 'openvsx-webui/lib/context';

interface Project {
project_id: string;
name: string;
url: string;
logo: string;
adopters: Adopter[];
}

interface Adopter {
name: string;
logo: string;
projects: string[];
homepage_url: string;
logo_white: string;
}

const AdoptersList: FunctionComponent = () => {
const [loaded, setLoaded] = useState(false);
const [adopters, setAdopters] = useState<Adopter[]>([]);

useEffect(() => {
if (loaded) return;

const abortController = new AbortController();
fetch(`https://api.eclipse.org/adopters/projects?working_group=cloud-development-tools`, {
signal: abortController.signal,
})
.then(async (res) => {
if (!res.ok) throw new Error('Failed to fetch adopters');

const projects = await res.json() as Project[];
const project = projects.find((p) => p.project_id == 'ecd.openvsx');
if(project) {
setAdopters(project.adopters);
}
})
.catch((err) => {
if (err instanceof DOMException && err.name === 'AbortError') return;
console.error(err);
})
.finally(() => abortController.signal.aborted || setLoaded(true));

return () => abortController.abort();
}, [loaded]);

if (adopters.length === 0) return <CircularProgress />;
return (
<Grid container spacing={3} mt={2}>
{ adopters.map(adopter =>
<AdopterItem
key={adopter.name}
name={adopter.name}
logo={adopter.logo}
logoWhite={adopter.logo_white}
url={adopter.homepage_url}
/>
)}
</Grid>
);
};

export default AdoptersList;

interface AdopterItemProps {
name: string;
logo?: string;
logoWhite?: string;
url?: string;
}

const bordered = (theme: Theme) => {
return {
border: '1px solid',
borderColor: theme.palette.mode === 'light'
? theme.palette.grey['300']
: theme.palette.grey['800']
};
};

const HeaderBox = styled(Box)(({ theme }: { theme: Theme }) => ({
...bordered(theme),
display: 'flex',
alignItems: 'center',
minHeight: '6rem',
backgroundColor: theme.palette.mode === 'light'
? theme.palette.grey['300']
: theme.palette.grey['800']
}));

const BodyBox = styled(Box)(({ theme }: { theme: Theme }) => ({
...bordered(theme),
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: theme.palette.background.default
}));

const GridContainer = styled(Grid)({
display: 'flex',
flexDirection: 'column',
alignItems: 'stretch',
height: '18rem',
textAlign: 'center',
});

const AdopterItem: FunctionComponent<AdopterItemProps> = ({ name, logo, logoWhite, url }) => {
const { pageSettings } = useContext(MainContext);
const styles = {
heading: {
width: '100%',
},
logoContainer: {
width: '100%',
maxWidth: '8rem',
maxHeight: '8rem',
},
logo: {
width: '100%',
height: '100%',
objectFit: 'contain',
}
};

let logoUrl = pageSettings.themeType == 'dark' ? logoWhite : logo;
if(logoUrl) {
logoUrl = 'https://api.eclipse.org/adopters/assets/images/adopters/' + logoUrl;
}

return (
<GridContainer item xs={12} md={4}>
<HeaderBox p={2}>
{ url
? <Link sx={styles.heading} href={url} variant="h6">{name}</Link>
: <Typography sx={styles.heading} variant="h6">{name}</Typography>
}
</HeaderBox>
<BodyBox p={2}>
<Box sx={styles.logoContainer}>
{ logoUrl
? <Box component='img' sx={styles.logo} src={logoUrl} alt='' />
: <Typography variant='h6'>{name}</Typography>
}
</Box>
</BodyBox>
</GridContainer>
);
};
Loading

0 comments on commit be987ba

Please sign in to comment.