Skip to content

Commit 5b39357

Browse files
committed
Check if local files are up to date
1 parent 2321788 commit 5b39357

File tree

8 files changed

+57
-0
lines changed

8 files changed

+57
-0
lines changed

src/client/components/ArticleInfo.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ interface Props {
1818
errorMessages: string[];
1919
qiitaItemUrl: string | null;
2020
slide: boolean;
21+
isOlderThanRemote: boolean;
2122
}
2223

2324
export const ArticleInfo = ({
@@ -28,6 +29,7 @@ export const ArticleInfo = ({
2829
errorMessages,
2930
qiitaItemUrl,
3031
slide,
32+
isOlderThanRemote,
3133
}: Props) => {
3234
const [isOpen, setIsOpen] = useState(
3335
localStorage.getItem("openInfoState") === "true" ? true : false
@@ -88,6 +90,18 @@ export const ArticleInfo = ({
8890
</InfoItem>
8991
<InfoItem title="スライドモード">{slide ? "ON" : "OFF"}</InfoItem>
9092
</details>
93+
{isOlderThanRemote && (
94+
<div css={errorContentsStyle}>
95+
<p css={errorStyle}>
96+
<MaterialSymbol fill={true} css={exclamationIconStyle}>
97+
error
98+
</MaterialSymbol>
99+
{
100+
"この記事ファイルの内容は、Qiita上の記事より古い可能性があります。"
101+
}
102+
</p>
103+
</div>
104+
)}
91105
{errorMessages.length > 0 && (
92106
<div css={errorContentsStyle}>
93107
{errorMessages.map((errorMessage, index) => (

src/client/components/Header.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { Snackbar, Message as SnackbarMessage } from "./Snackbar";
1313
interface Props {
1414
id?: string;
1515
isItemPublishable: boolean;
16+
isOlderThanRemote: boolean;
1617
itemPath: string;
1718
basename: string | null;
1819
handleMobileOpen: () => void;
@@ -21,6 +22,7 @@ interface Props {
2122
export const Header = ({
2223
id,
2324
isItemPublishable,
25+
isOlderThanRemote,
2426
itemPath,
2527
basename,
2628
handleMobileOpen,
@@ -32,6 +34,16 @@ export const Header = ({
3234
const mobileSize = currentWidth <= breakpoint.S;
3335

3436
const handlePublish = () => {
37+
if (isOlderThanRemote) {
38+
if (
39+
!window.confirm(
40+
"この記事はQiita上の記事より古い可能性があります。上書きしますか?"
41+
)
42+
) {
43+
return;
44+
}
45+
}
46+
3547
const params = {
3648
method: "POST",
3749
headers: {

src/client/pages/items/show.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export const ItemsShow = () => {
8484
isItemPublishable={
8585
item.modified && item.error_messages.length === 0
8686
}
87+
isOlderThanRemote={item.is_older_than_remote}
8788
itemPath={item.item_path}
8889
id={id}
8990
basename={basename}
@@ -98,6 +99,7 @@ export const ItemsShow = () => {
9899
errorMessages={item.error_messages}
99100
qiitaItemUrl={item.qiita_item_url}
100101
slide={item.slide}
102+
isOlderThanRemote={item.is_older_than_remote}
101103
/>
102104
<div css={articleWrapStyle}>
103105
<Article

src/commands/publish.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export const publish = async (argv: string[]) => {
1313
const args = arg(
1414
{
1515
"--all": Boolean,
16+
"--force": Boolean,
17+
"-f": "--force",
1618
},
1719
{ argv }
1820
);
@@ -41,6 +43,7 @@ export const publish = async (argv: string[]) => {
4143
}
4244

4345
// Validate
46+
const enableForcePublish = args["--force"];
4447
const invalidItemMessages = targetItems.reduce((acc, item) => {
4548
const frontmatterErrors = checkFrontmatterType(item);
4649
if (frontmatterErrors.length > 0)
@@ -50,6 +53,16 @@ export const publish = async (argv: string[]) => {
5053
if (validationErrors.length > 0)
5154
return [...acc, { name: item.name, errors: validationErrors }];
5255

56+
if (!enableForcePublish && item.isOlderThanRemote) {
57+
return [
58+
...acc,
59+
{
60+
name: item.name,
61+
errors: ["内容がQiita上の記事より古い可能性があります"],
62+
},
63+
];
64+
}
65+
5366
return acc;
5467
}, [] as { name: string; errors: string[] }[]);
5568
if (invalidItemMessages.length > 0) {

src/lib/entities/qiita-item.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export class QiitaItem {
88
public readonly rawBody: string;
99
public readonly name: string;
1010
public readonly modified: boolean;
11+
public readonly isOlderThanRemote: boolean;
1112
public readonly itemsShowPath: string;
1213
public readonly published: boolean;
1314
public readonly itemPath: string;
@@ -23,6 +24,7 @@ export class QiitaItem {
2324
rawBody,
2425
name,
2526
modified,
27+
isOlderThanRemote,
2628
itemsShowPath,
2729
published,
2830
itemPath,
@@ -37,6 +39,7 @@ export class QiitaItem {
3739
rawBody: string;
3840
name: string;
3941
modified: boolean;
42+
isOlderThanRemote: boolean;
4043
itemsShowPath: string;
4144
published: boolean;
4245
itemPath: string;
@@ -51,6 +54,7 @@ export class QiitaItem {
5154
this.rawBody = rawBody;
5255
this.name = name;
5356
this.modified = modified;
57+
this.isOlderThanRemote = isOlderThanRemote;
5458
this.itemsShowPath = itemsShowPath;
5559
this.published = published;
5660
this.itemPath = itemPath;

src/lib/file-system-repo.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ class FileContent {
135135
);
136136
}
137137

138+
isOlderThan(otherFileContent: FileContent | null): boolean {
139+
if (!otherFileContent) return false;
140+
const updatedAt = new Date(this.updatedAt);
141+
const otherUpdatedAt = new Date(otherFileContent.updatedAt);
142+
143+
return updatedAt < otherUpdatedAt;
144+
}
145+
138146
clone({ id }: { id: string }): FileContent {
139147
return new FileContent({
140148
title: this.title,
@@ -353,6 +361,7 @@ export class FileSystemRepo {
353361
slide: localFileContent.slide,
354362
name: basename,
355363
modified: !localFileContent.equals(remoteFileContent),
364+
isOlderThanRemote: localFileContent.isOlderThan(remoteFileContent),
356365
itemsShowPath: this.generateItemsShowPath(localFileContent.id, basename),
357366
published: remoteFileContent !== null,
358367
itemPath,
@@ -388,6 +397,7 @@ export class FileSystemRepo {
388397
slide: localFileContent.slide,
389398
name: basename,
390399
modified: !localFileContent.equals(remoteFileContent),
400+
isOlderThanRemote: localFileContent.isOlderThan(remoteFileContent),
391401
itemsShowPath: this.generateItemsShowPath(localFileContent.id, basename),
392402
published: remoteFileContent !== null,
393403
itemPath,

src/lib/view-models/items.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type ItemsIndexViewModel = {
1515

1616
export type ItemsShowViewModel = {
1717
error_messages: string[];
18+
is_older_than_remote: boolean;
1819
item_path: string;
1920
modified: boolean;
2021
organization_url_name: string | null;

src/server/api/items.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ const itemsShow = async (req: Express.Request, res: Express.Response) => {
9595

9696
const result: ItemsShowViewModel = {
9797
error_messages: errorMessages,
98+
is_older_than_remote: item.isOlderThanRemote,
9899
item_path: itemPath,
99100
modified,
100101
organization_url_name: item.organizationUrlName,

0 commit comments

Comments
 (0)