Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #115 codeviewer #116

Merged
merged 3 commits into from
Nov 21, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function CodeSideBar({ className, ...props }: CodeSideBarProps) {
const setCurrentCode = useCodeViewActionContext();

return (
<div className={cn('flex flex-col rounded-lg shadow-md py-2 h-full', className)} {...props}>
<div className={cn('flex flex-col rounded-lg shadow-md py-2 h-full overflow-scroll', className)} {...props}>
{value.map((v, i) => (
<Button
variant={'link'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type CodeViewProviderProps = {

export function CodeViewProvider({ value, children, current: currentIndex = 0 }: CodeViewProviderProps) {
const [current, setCurrent] = useState(currentIndex);

const setCurrentCode = (index: number) => setCurrent(index);

return (
Expand Down
68 changes: 57 additions & 11 deletions apps/frontend/src/feature/codeView/component/CodeViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { HTMLProps } from 'react';
import { cn } from '@froxy/design/utils';
import { Markdown } from '@froxy/react-markdown';
import { Text } from '@/components';
import { useCodeViewContext } from '@/feature/codeView/hook';

type CodeViewerProps = {
Expand All @@ -9,33 +10,78 @@ type CodeViewerProps = {
} & HTMLProps<HTMLDivElement>;

const LANGUAGES_EXT = {
typescript: 'ts',
TypeScript: 'ts',
ts: 'ts',
javascript: 'js',
js: 'js'
Ts: 'ts',
JavaScript: 'js',
Js: 'js',
js: 'js',
json: 'json',
JSON: 'json'
} as const;

const getLanguage = (language: string) => {
return LANGUAGES_EXT[language as keyof typeof LANGUAGES_EXT];
const CANT_VIEW_EXT = [
'png',
'jpg',
'jpeg',
'gif',
'svg',
'bmp',
'webp',
'ico',
'tiff',
'tif',
'raw',
'heif',
'heic',
'apng',
'avif',
'jxl',
'mp4',
'mov',
'avi',
'wmv',
'flv',
'mkv',
'webm'
];

const getCode = (ext: string): (typeof LANGUAGES_EXT)[keyof typeof LANGUAGES_EXT] | undefined => {
return LANGUAGES_EXT[ext as keyof typeof LANGUAGES_EXT];
};

// TODO : 아주 막연하게 구현된 컴포넌트, 추후에 스타일 리팩터링 필요
export function CodeViewer({ children, className, ...props }: CodeViewerProps) {
export function CodeViewer({ className, ...props }: CodeViewerProps) {
const { value, current } = useCodeViewContext();

const language = getLanguage(value[current].language);
const file = value[current];
const content = file?.content || '';
const filename = file?.filename || '';
const ext = filename.split('.')?.pop() || '';

const language = getCode(ext);

const markdown = language ? `\`\`\`${language}\n${file.content}\n \`\`\`` : content;

const content = language ? `\`\`\`${language}\n ${value[current].content}\n \`\`\`` : value[current].content;
if (CANT_VIEW_EXT.includes(ext))
return (
<div className={cn('w-full h-full rounded-lg shadow-lg text-sm flex flex-col items-center justify-center')}>
<img src={'/image/logoIcon.svg'} alt={filename} className="w-40 h-40 object-contain" />
<Text>지원하지 않는 확장자입니다.</Text>
</div>
);

return (
<Markdown
className={cn(
'w-full h-full rounded-lg shadow-lg',
language ? '[&>figure]:h-full [&>figure>pre]:h-full [&>figure>pre]:m-0' : 'p-2',
'w-full h-full rounded-lg shadow-lg text-sm bg-[#f6f8fa]',
language
? '[&>figure]:h-full [&>figure]:w-full [&>figure>pre]:h-full [&>figure>pre]:w-full [&>figure>pre]:m-0'
: 'p-2',
'overflow-scroll',
className
)}
markdown={children || content}
markdown={markdown}
{...props}
/>
);
Expand Down
6 changes: 4 additions & 2 deletions apps/frontend/src/feature/lotus/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,11 @@ export function LotusLink({ children, className }: LotusLinkProps) {
type LotusLogoProps = HTMLProps<HTMLImageElement>;

export function LotusLogo({ className, ...props }: LotusLogoProps) {
const { logo, title } = useLotusContext();
const { title, author } = useLotusContext();

return <img src={logo} alt={title} className={cn('w-16 h-16 rounded-full', className)} {...props} />;
const image = author?.profile || '/image/logoIcon.svg';

return <img src={image} alt={title} className={cn('w-16 h-16 rounded-full', className)} {...props} />;
}

export function LotusProvider({ children, lotus }: { children: React.ReactNode; lotus: LotusType }) {
Expand Down
4 changes: 3 additions & 1 deletion apps/frontend/src/widget/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export function Header() {
navigate({ to: '/lotus' });
};

const image = data?.profile || '/image/exampleImage.jpeg';

return (
<header className="flex justify-center mb-7 w-full shadow-md">
<div className="w-full max-w-screen-xl py-5 px-4 sm:px-6 lg:px-8 flex justify-between items-center">
Expand All @@ -28,7 +30,7 @@ export function Header() {
<LogoutButton />
</div>

<img className="w-10 h-10 rounded-full" src="/image/exampleImage.jpeg" alt="프로필 사진" />
<img className="w-10 h-10 rounded-full" src={image} alt="프로필 사진" />
</>
) : (
<LoginButton variant={'default'}>Login</LoginButton>
Expand Down
10 changes: 6 additions & 4 deletions apps/frontend/src/widget/lotusCreate/SuspenseGistFiles.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { CodeView } from '@/feature/codeView';
import { useUserGistFileSuspenseQuery } from '@/feature/user/query';

import '@/app/style/github.css';

export function SuspenseGistFiles({ gistId }: { gistId: string }) {
const { data: files } = useUserGistFileSuspenseQuery({ gistId });

const readmeIndex = files.findIndex(({ filename }) => filename === 'README.md');
const defaultIndex = files.findIndex(({ filename }) => filename === 'README.md') || 0;

return (
<CodeView value={files} current={readmeIndex}>
<div className="flex github gap-6 w-full h-[600px] mt-20 pb-10 overflow-hidden">
<CodeView value={files} current={defaultIndex}>
<div className="flex github gap-6 w-full h-[600px] mt-20 pb-10 px-2 overflow-hidden">
<CodeView.SideBar className="h-full min-w-48" />
<CodeView.Viewer className="block h-[600px]" />
<CodeView.Viewer className="block h-full" />
</div>
</CodeView>
);
Expand Down
8 changes: 4 additions & 4 deletions apps/frontend/src/widget/lotusDetail/SuspenseLotusFiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ export function SuspenseLotusFiles({ id }: { id: string }) {
data: { files }
} = useLotusSuspenseQuery({ id });

const readmeIndex = files.findIndex(({ filename }) => filename === 'README.md');
const defaultIndex = files.findIndex(({ filename }) => filename === 'README.md');

return (
<CodeView value={files} current={readmeIndex}>
<div className="flex github gap-6 w-full h-[600px] pb-10 overflow-hidden">
<CodeView value={files} current={defaultIndex}>
<div className="flex github gap-4 w-full h-[600px] pb-10 px-2 overflow-hidden">
<CodeView.SideBar className="h-full min-w-48" />
<CodeView.Viewer className="block h-[600px]" />
<CodeView.Viewer className="block h-full" />
</div>
</CodeView>
);
Expand Down