Skip to content

Commit

Permalink
Merge pull request #253 from maretol/fix-contact
Browse files Browse the repository at this point in the history
Fix contact
  • Loading branch information
maretol authored Jan 12, 2025
2 parents ba2d832 + 01b3f2e commit c1fab49
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 79 deletions.
107 changes: 57 additions & 50 deletions cms-data-fetcher/src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,44 @@ export function parse(content: string) {
}

function getPOption(text: string) {
let pOpt = 'normal'
if (isImage(text)) {
pOpt = 'image'
} else if (isPhoto(text)) {
pOpt = 'photo'
} else if (isComicPage(text)) {
pOpt = 'comic'
} else if (isYouTube(text)) {
pOpt = 'youtube'
} else if (isTwitter(text)) {
pOpt = 'twitter'
} else if (isAmazon(text)) {
pOpt = 'amazon'
} else if (isBlog(text)) {
pOpt = 'blog'
} else if (isArtifact(text)) {
pOpt = 'artifact'
} else if (isURL(text)) {
pOpt = 'url'
} else if (text === '') {
pOpt = 'empty'
} else if (isCommand(text)) {
pOpt = text.replaceAll('/', '')
// URLではない場合
if (!URL.canParse(text)) {
if (text === '') {
return 'empty'
} else if (isCommand(text)) {
return text.replaceAll('/', '')
}
return 'normal'
}

// URLの場合
const textURL = new URL(text)
if (isImage(textURL.hostname, text)) {
return 'image'
} else if (isPhoto(textURL.hostname, text)) {
return 'photo'
} else if (isComicPage(textURL.hostname, textURL.pathname)) {
return 'comic'
} else if (isYouTube(textURL.hostname)) {
return 'youtube'
} else if (isTwitter(textURL.hostname)) {
return 'twitter'
} else if (isAmazon(textURL.hostname)) {
return 'amazon'
} else if (isBlog(textURL.hostname, textURL.pathname)) {
return 'blog'
} else if (isArtifact(textURL.hostname, textURL.pathname)) {
return 'artifact'
} else if (isURL(textURL)) {
return 'url'
} else {
// URLとしてパースできたが、http/https以外のプロトコルの場合は通常のテキストとして扱う
return 'normal'
}
return pOpt
}

function isImage(text: string) {
if (text.indexOf('https://r2.maretol.xyz/') === 0) {
function isImage(hostname: string, text: string) {
if (hostname === 'r2.maretol.xyz') {
const ext = text.split('.').pop() || ''
if (['jpg', 'jpeg', 'png', 'gif'].includes(ext)) {
return true
Expand All @@ -77,51 +86,47 @@ function isImage(text: string) {
}
}

function isPhoto(text: string) {
if (text.indexOf('https://photos.maretol.xyz') === 0) {
const photoURL = text.split('@@')[0] // 画像URL。@@以降はキャプション
function isPhoto(hostname: string, text: string) {
const photoDomain = ['photos.maretol.xyz', 'capture.maretol.xyz']
if (photoDomain.includes(hostname)) {
const photoURL = text.split('@@')[0] // 画像URL。@@以降はタイトルやキャプション
const ext = photoURL.split('.').pop() || ''
if (['jpg', 'jpeg', 'png', 'gif'].includes(ext)) {
return true
}
}
return
return false
}

function isComicPage(text: string) {
return text.indexOf('https://www.maretol.xyz/comics/') === 0 || text.indexOf('https://maretol.xyz/comics/') === 0
function isComicPage(hostname: string, pathname: string) {
const comicDomain = ['maretol.xyz', 'www.maretol.xyz']
return comicDomain.includes(hostname) && pathname.indexOf('/comics/') === 0
}

function isYouTube(text: string) {
return text.indexOf('https://youtu.be/') === 0 || text.indexOf('https://www.youtube.com/') === 0
function isYouTube(hostname: string) {
return ['youtu.be', 'www.youtube.com'].includes(hostname)
}

function isTwitter(text: string) {
return (
text.indexOf('https://twitter.com/') === 0 ||
text.indexOf('https://www.twitter.com/') === 0 ||
text.indexOf('https://x.com/') === 0
)
function isTwitter(hostname: string) {
return ['twitter.com', 'www.twitter.com', 'x.com'].includes(hostname)
}

function isAmazon(text: string) {
return text.indexOf('https://www.amazon.co.jp/') === 0 || text.indexOf('https://amzn.to/') === 0
function isAmazon(hostname: string) {
return ['www.amazon.co.jp', 'amzn.to'].includes(hostname)
}

// ブログ記事のリンクの場合
function isBlog(text: string) {
return text.indexOf('https://www.maretol.xyz/blog/') === 0 || text.indexOf('https://maretol.xyz/blog/') === 0
function isBlog(hostname: string, pathname: string) {
return ['maretol.xyz', 'www.maretol.xyz'].includes(hostname) && pathname.indexOf('/blog/') === 0
}

// artifactのリンクの場合
function isArtifact(text: string) {
return (
text.indexOf('https://www.maretol.xyz/artifacts/') === 0 || text.indexOf('https://maretol.xyz/artifacts/') === 0
)
function isArtifact(hostname: string, pathname: string) {
return ['maretol.xyz', 'www.maretol.xyz'].includes(hostname) && pathname.indexOf('/artifacts/') === 0
}

function isURL(text: string) {
return text.indexOf('https://') === 0
function isURL(url: URL) {
return url.protocol === 'http:' || url.protocol === 'https:'
}

function isCommand(text: string) {
Expand Down Expand Up @@ -150,3 +155,5 @@ function getSubText(text: string) {
}
return null
}

export { getPOption }
108 changes: 84 additions & 24 deletions cms-data-fetcher/test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,85 @@
// test/index.spec.ts
import { env, createExecutionContext, waitOnExecutionContext, SELF } from 'cloudflare:test';
import { describe, it, expect } from 'vitest';
import worker from '../src/index';
import { describe, it, expect } from 'vitest'
import { getPOption } from '../src/parse'

// For now, you'll need to do something like this to get a correctly-typed
// `Request` to pass to `worker.fetch()`.
const IncomingRequest = Request<unknown, IncomingRequestCfProperties>;

describe('Hello World worker', () => {
it('responds with Hello World! (unit style)', async () => {
const request = new IncomingRequest('http://example.com');
// Create an empty context to pass to `worker.fetch()`.
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
// Wait for all `Promise`s passed to `ctx.waitUntil()` to settle before running test assertions
await waitOnExecutionContext(ctx);
expect(await response.text()).toMatchInlineSnapshot(`"Hello World!"`);
});

it('responds with Hello World! (integration style)', async () => {
const response = await SELF.fetch('https://example.com');
expect(await response.text()).toMatchInlineSnapshot(`"Hello World!"`);
});
});
describe('parse_getPOptionのテスト', () => {
it('通常テキストの場合', () => {
const text = 'test text'
const result = getPOption(text)
expect(result).toBe('normal')
})
it('空文字の場合', () => {
const text = ''
const result = getPOption(text)
expect(result).toBe('empty')
})
it('画像の場合', () => {
const text = 'https://r2.maretol.xyz/test.png'
const result = getPOption(text)
expect(result).toBe('image')
})
it('写真の場合', () => {
const text = ['https://photos.maretol.xyz/test.jpg', 'https://capture.maretol.xyz/test.jpg']
text.forEach((t) => {
const result = getPOption(t)
expect(result).toBe('photo')
})
})
it('写真でサブテキストがあった場合', () => {
const text = 'https://photos.maretol.xyz/test.jpg@@subtext_key::subtext_value@@subtext::サブテキスト'
const result = getPOption(text)
expect(result).toBe('photo')
})
it('漫画リンクの場合', () => {
const text = 'https://www.maretol.xyz/comics/test'
const result = getPOption(text)
expect(result).toBe('comic')
})
it('YouTubeリンクの場合', () => {
const text = ['https://www.youtube.com/watch?v=test', 'https://youtu.be/test']
text.forEach((t) => {
const result = getPOption(t)
expect(result).toBe('youtube')
})
}),
it('Twitterリンクの場合', () => {
const text = ['https://twitter.com/test', 'https://www.twitter.com/test', 'https://x.com/test']
text.forEach((t) => {
const result = getPOption(t)
expect(result).toBe('twitter')
})
})
it('Amazonリンクの場合', () => {
const text = ['https://www.amazon.co.jp/test', 'https://amzn.to/test']
text.forEach((t) => {
const result = getPOption(t)
expect(result).toBe('amazon')
})
})
it('ブログリンクの場合', () => {
const text = 'https://www.maretol.xyz/blog/test'
const result = getPOption(text)
expect(result).toBe('blog')
})
it('artifactリンクの場合', () => {
const text = 'https://www.maretol.xyz/artifacts/test'
const result = getPOption(text)
expect(result).toBe('artifact')
})
it('その他のURLの場合', () => {
const text = 'https://example.com'
const result = getPOption(text)
expect(result).toBe('url')
})
it('コマンド入力の場合', () => {
const text = '/test_command'
const result = getPOption(text)
expect(result).toBe('test_command')
})
it('特殊なテキストの場合', () => {
const text = ['text://hogehoge', '途中にURLが入っている場合。https://example.comみたいな']
text.forEach((t) => {
const result = getPOption(t)
expect(result).toBe('normal')
})
})
})
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"deploy:page": "npm run --workspace=pages deploy-prd",
"deploy-stg:page": "npm run --workspace=pages deploy-stg",
"build:page": "npm run --workspace=pages pages:build",
"lint:page": "npm run --workspace=pages lint"
"lint:page": "npm run --workspace=pages lint",
"test:cms": "npm run --workspace=cms-data-fetcher test"
},
"author": "maretol",
"private": true,
Expand Down
5 changes: 5 additions & 0 deletions pages/app/artifacts/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import BaseLayout from '@/components/large/base_layout'

export default function ArtifactsLayout({ children }: { children: React.ReactNode }) {
return <BaseLayout>{children}</BaseLayout>
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function Modal({ imageSrc }: { imageSrc: string }) {
alt=""
width={1000}
height={1000}
className="mb-5 mt-0 w-full max-w-fit h-full max-h-fit shadow-lg"
className="my-10 w-full max-w-fit h-full max-h-fit shadow-lg"
/>
</div>
</DialogContent>
Expand Down
4 changes: 2 additions & 2 deletions pages/components/middle/comicbook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export default function ComicBook(props: ComicBookProps) {
}

return (
<div className="h-screen w-full bg-gray-700 static" onKeyDown={keyEvent} tabIndex={0}>
<div className="h-[95vh] w-full bg-gray-700 static" onKeyDown={keyEvent} tabIndex={0}>
<div
className={cn(
'absolute top-0 left-0 w-full flex justify-center items-center bg-gray-300',
Expand Down Expand Up @@ -138,7 +138,7 @@ export default function ComicBook(props: ComicBookProps) {
key={i}
className={cn('h-full w-full flex justify-center items-center', i === currentPage ? '' : 'hidden')}
>
<ComicImage src={src} alt="" className="h-full w-full max-h-fit max-w-max" />
<ComicImage src={src} alt="" className="h-full w-auto" />
</div>
)
case 'pair':
Expand Down
2 changes: 1 addition & 1 deletion pages/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
'fixed left-[50%] top-[50%] max-h-full max-w-full w-max z-50 grid translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200',
'fixed left-[50%] top-[50%] max-h-full max-w-full w-max z-50 flex justify-center items-center translate-x-[-50%] translate-y-[-50%] border bg-background shadow-lg duration-200',
className
)}
{...props}
Expand Down

0 comments on commit c1fab49

Please sign in to comment.