pinkmine/frontend/src/misc-components/unreaded-flag.tsx

78 lines
2.2 KiB
TypeScript

import React from 'react';
import Css from './unreaded-flag.module.css';
import { observer } from 'mobx-react-lite';
import { Instance, types } from 'mobx-state-tree';
import { RedmineTypes } from '../redmine-types';
import {
GetIssueReadingTimestamp,
SetIssueReadingTimestamp,
} from '../utils/unreaded-provider';
export const Store = types
.model({
issue: types.frozen<RedmineTypes.ExtendedIssue>(),
readingTimestamp: types.number,
})
.actions((self) => {
return {
read: () => {
self.readingTimestamp = SetIssueReadingTimestamp(self.issue.id);
},
};
})
.views((self) => {
return {
getUpdatedTimestap(): number {
if (self.issue.journals) {
let lastComment: RedmineTypes.Journal | undefined;
for (let i = self.issue.journals.length - 1; i >= 0; i--) {
const journal = self.issue.journals[i];
if (journal.notes) {
lastComment = journal;
break;
}
}
if (lastComment) {
return new Date(lastComment.created_on).getTime();
}
}
return 0;
},
getClassName(): string {
let className = Css.circle;
const updatedTimestamp = this.getUpdatedTimestap();
if (self.readingTimestamp < updatedTimestamp) {
className += ` ${Css.unreaded}`;
}
console.debug(
`Unreaded flag getClassName: issueId=${self.issue.id}; readingTimestamp=${self.readingTimestamp}; updatedTimestamp=${updatedTimestamp}; className=${className}`,
); // DEBUG
return className;
},
};
});
export function CreateStoreFromLocalStorage(issue: RedmineTypes.ExtendedIssue) {
const timestamp = GetIssueReadingTimestamp(issue.id);
return Store.create({
issue: issue,
readingTimestamp: timestamp,
});
}
export type Props = {
store: Instance<typeof Store>;
};
export const UnreadedFlag = observer((props: Props): JSX.Element => {
const className = props.store.getClassName();
return (
<span
className={className}
onClick={(e) => {
e.stopPropagation();
props.store.read();
}}
></span>
);
});