diff options
Diffstat (limited to 'FrontEnd/src/app/views/timeline-common')
6 files changed, 84 insertions, 61 deletions
| diff --git a/FrontEnd/src/app/views/timeline-common/Timeline.tsx b/FrontEnd/src/app/views/timeline-common/Timeline.tsx index fd051d45..9047919c 100644 --- a/FrontEnd/src/app/views/timeline-common/Timeline.tsx +++ b/FrontEnd/src/app/views/timeline-common/Timeline.tsx @@ -4,6 +4,7 @@ import clsx from "clsx";  import { TimelinePostInfo } from "@/services/timeline";  import TimelineItem from "./TimelineItem"; +import TimelineTop from "./TimelineTop";  export interface TimelinePostInfoEx extends TimelinePostInfo {    deletable: boolean; @@ -13,6 +14,7 @@ export type TimelineDeleteCallback = (index: number, id: number) => void;  export interface TimelineProps {    className?: string; +  style?: React.CSSProperties;    posts: TimelinePostInfoEx[];    onDelete: TimelineDeleteCallback;    onResize?: () => void; @@ -51,7 +53,12 @@ const Timeline: React.FC<TimelineProps> = (props) => {    }, [posts, onDelete]);    return ( -    <div ref={props.containerRef} className={clsx("timeline", props.className)}> +    <div +      ref={props.containerRef} +      style={props.style} +      className={clsx("timeline", props.className)} +    > +      <TimelineTop height="56px" />        {(() => {          const length = posts.length;          return posts.map((post, i) => { diff --git a/FrontEnd/src/app/views/timeline-common/TimelineItem.tsx b/FrontEnd/src/app/views/timeline-common/TimelineItem.tsx index 4db23371..5ccc5523 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelineItem.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelineItem.tsx @@ -93,12 +93,12 @@ const TimelineItem: React.FC<TimelineItemProps> = (props) => {            {current && <div className="timeline-line-segment current-end" />}          </div>        </div> -      <div className="timeline-content-area"> +      <div className="timeline-item-card">          <div>            <span className="mr-2"> -            <span className="text-primary white-space-no-wrap mr-2"> +            <small className="text-secondary white-space-no-wrap mr-2">                {props.post.time.toLocaleString(i18n.languages)} -            </span> +            </small>              <small className="text-dark">{props.post.author.nickname}</small>            </span>            {more != null ? ( @@ -138,33 +138,33 @@ const TimelineItem: React.FC<TimelineItemProps> = (props) => {              }            })()}          </div> +        {more != null && more.isOpen ? ( +          <> +            <div +              className="position-absolute position-lt w-100 h-100 mask d-flex justify-content-center align-items-center" +              onClick={more.toggle} +            > +              <Svg +                src={trashIcon} +                className="text-danger icon-button large" +                onClick={(e) => { +                  toggleDeleteDialog(); +                  e.stopPropagation(); +                }} +              /> +            </div> +            {deleteDialog ? ( +              <TimelinePostDeleteConfirmDialog +                toggle={() => { +                  toggleDeleteDialog(); +                  more.toggle(); +                }} +                onConfirm={more.onDelete} +              /> +            ) : null} +          </> +        ) : null}        </div> -      {more != null && more.isOpen ? ( -        <> -          <div -            className="position-absolute position-lt w-100 h-100 mask d-flex justify-content-center align-items-center" -            onClick={more.toggle} -          > -            <Svg -              src={trashIcon} -              className="text-danger icon-button large" -              onClick={(e) => { -                toggleDeleteDialog(); -                e.stopPropagation(); -              }} -            /> -          </div> -          {deleteDialog ? ( -            <TimelinePostDeleteConfirmDialog -              toggle={() => { -                toggleDeleteDialog(); -                more.toggle(); -              }} -              onConfirm={more.onDelete} -            /> -          ) : null} -        </> -      ) : null}      </div>    );  }; diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx index 6c2c43c1..036577b1 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx @@ -16,7 +16,6 @@ import Timeline, {    TimelinePostInfoEx,    TimelineDeleteCallback,  } from "./Timeline"; -import TimelineTop from "./TimelineTop";  import TimelinePostEdit, { TimelinePostSendCallback } from "./TimelinePostEdit";  import { TimelineSyncStatus } from "./SyncStatusBadge"; @@ -48,13 +47,10 @@ export default function TimelinePageTemplateUI<TManageItems>(    const { t } = useTranslation(); -  const bottomSpaceRef = React.useRef<HTMLDivElement | null>(null); +  const [bottomSpaceHeight, setBottomSpaceHeight] = React.useState<number>(0);    const onPostEditHeightChange = React.useCallback((height: number): void => { -    const { current: bottomSpaceDiv } = bottomSpaceRef; -    if (bottomSpaceDiv != null) { -      bottomSpaceDiv.style.height = `${height}px`; -    } +    setBottomSpaceHeight(height);      if (height === 0) {        const alertHost = getAlertHost();        if (alertHost != null) { @@ -178,6 +174,9 @@ export default function TimelinePageTemplateUI<TManageItems>(            timelineBody = (              <Timeline +              style={{ +                minHeight: `calc(100vh - 56px - ${bottomSpaceHeight}px)`, +              }}                containerRef={timelineRef}                posts={posts}                onDelete={props.onDelete} @@ -188,7 +187,10 @@ export default function TimelinePageTemplateUI<TManageItems>(              timelineBody = (                <>                  {timelineBody} -                <div ref={bottomSpaceRef} className="flex-fix-length" /> +                <div +                  style={{ height: bottomSpaceHeight }} +                  className="flex-fix-length" +                />                  <TimelinePostEdit                    className="fixed-bottom"                    onPost={props.onPost} @@ -226,7 +228,6 @@ export default function TimelinePageTemplateUI<TManageItems>(              collapse={cardCollapse}              toggleCollapse={toggleCardCollapse}            /> -          <TimelineTop height="56px" />            {timelineBody}          </>        ); diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePropertyChangeDialog.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePropertyChangeDialog.tsx index 223525f9..ee49586e 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePropertyChangeDialog.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePropertyChangeDialog.tsx @@ -6,9 +6,7 @@ import {    TimelineChangePropertyRequest,  } from "@/services/timeline"; -import OperationDialog, { -  OperationSelectInputInfoOption, -} from "../common/OperationDialog"; +import OperationDialog from "../common/OperationDialog";  export interface TimelinePropertyInfo {    title: string; @@ -45,12 +43,10 @@ const TimelinePropertyChangeDialog: React.FC<TimelinePropertyChangeDialogProps>          {            type: "select",            label: "timeline.dialogChangeProperty.visibility", -          options: kTimelineVisibilities.map<OperationSelectInputInfoOption>( -            (v) => ({ -              label: labelMap[v], -              value: v, -            }) -          ), +          options: kTimelineVisibilities.map((v) => ({ +            label: labelMap[v], +            value: v, +          })),            initValue: props.oldInfo.visibility,          },          { @@ -64,13 +60,13 @@ const TimelinePropertyChangeDialog: React.FC<TimelinePropertyChangeDialogProps>        onProcess={([newTitle, newVisibility, newDescription]) => {          const req: TimelineChangePropertyRequest = {};          if (newTitle !== props.oldInfo.title) { -          req.title = newTitle as string; +          req.title = newTitle;          }          if (newVisibility !== props.oldInfo.visibility) {            req.visibility = newVisibility as TimelineVisibility;          }          if (newDescription !== props.oldInfo.description) { -          req.description = newDescription as string; +          req.description = newDescription;          }          return props.onProcess(req);        }} diff --git a/FrontEnd/src/app/views/timeline-common/timeline-background.svg b/FrontEnd/src/app/views/timeline-common/timeline-background.svg new file mode 100644 index 00000000..b72c448b --- /dev/null +++ b/FrontEnd/src/app/views/timeline-common/timeline-background.svg @@ -0,0 +1,4 @@ +<svg viewBox="0 0 100 80" xmlns="http://www.w3.org/2000/svg" stroke="rgba(255,196,0,0.6)">
 +    <line x1="0" y1="0" x2="100" y2="40" stroke-width="5" />
 +    <line x1="0" y1="80" x2="100" y2="40" stroke-width="5" />
 +</svg>
\ No newline at end of file diff --git a/FrontEnd/src/app/views/timeline-common/timeline-common.sass b/FrontEnd/src/app/views/timeline-common/timeline-common.sass index 4151bfcc..8d9ee04d 100644 --- a/FrontEnd/src/app/views/timeline-common/timeline-common.sass +++ b/FrontEnd/src/app/views/timeline-common/timeline-common.sass @@ -4,8 +4,13 @@    z-index: 0    position: relative +  background-image: url("views/timeline-common/timeline-background.svg") +  background-size: 100% auto +  background-repeat: no-repeat repeat +    &-item -    display: flex +    position: relative +    padding: 0.5em  $timeline-line-width: 7px  $timeline-line-node-radius: 18px @@ -30,11 +35,15 @@ $timeline-line-color-current: #36c2e6  .timeline-line    &-area-container +    position: absolute      display: flex      justify-content: flex-end      padding-right: 5px +    z-index: 1 -    flex: 0 0 auto +    top: 0em +    bottom: 0em +    left: 0.5em      width: 60px    &-area @@ -48,14 +57,14 @@ $timeline-line-color-current: #36c2e6      background: $timeline-line-color      &.start -      height: 14px +      height: 1.4em        flex: 0 0 auto      &.end        flex: 1 1 auto      &.current-end -      height: 20px +      height: 2em        flex: 0 0 auto        background: linear-gradient($timeline-line-color-current, transparent) @@ -78,13 +87,16 @@ $timeline-line-color-current: #36c2e6      animation-name: timeline-line-node-noncurrent  .timeline-top -  display: flex -  justify-content: space-between +  position: relative +  text-align: right    .timeline-line-segment      flex: 1 1 auto  .current +  &.timeline-item +    padding-bottom: 2.5em +    .timeline-line      &-segment @@ -97,9 +109,15 @@ $timeline-line-color-current: #36c2e6      &-node        animation-name: timeline-line-node-current -.timeline-content-area -  padding: 10px 0 -  flex-grow: 1 +.timeline-item-card +  @extend .cru-card +  @extend .clearfix +  position: relative +  padding: 0.5em 2em 0.5em 60px +  transition: background 0.5s + +  &:hover +    background: $gray-200  .timeline-item-delete-button    position: absolute @@ -121,9 +139,6 @@ $timeline-line-color-current: #36c2e6    background: change-color($color: white, $alpha: 0.8)    z-index: 100 -.timeline-page-top-space -  transition: height 0.5s -  .timeline-sync-state-badge    font-size: 0.8em    padding: 3px 8px | 
