Skip to content

Commit

Permalink
fix: improve problems of lectures 7-8
Browse files Browse the repository at this point in the history
  • Loading branch information
exKAZUu committed Oct 12, 2024
1 parent 1741a10 commit 944f4e8
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 45 deletions.
1 change: 0 additions & 1 deletion src/app/(withAuth)/admin/problems/[problemId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ async function fetchUserProblemInfo(problemId: ProblemId): Promise<UserProblemIn
submissions: { where: { isCorrect: false }, select: { id: true } },
},
});
console.log('sessions:', sessions);

return await Promise.all(
sessions.map(async (session) => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import { zenkakuAlphanumericalsToHankaku } from '@willbooster/shared-lib';
import fastDeepEqual from 'fast-deep-equal';
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import type { BoxProps } from '@chakra-ui/react';
import { keyframes } from '@emotion/react';
import React, { useMemo } from 'react';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use client';

import type { ProblemSession } from '@prisma/client';
import { useRouter } from 'next/navigation';
import React, { useCallback, useMemo, useRef, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';

import { MAX_CHALLENGE_COUNT } from '../../../../../../../../constants';
import { backendTrpcReact } from '../../../../../../../../infrastructures/trpcBackend/client';
Expand Down Expand Up @@ -47,7 +49,6 @@ export const ProblemBody: React.FC<Props> = (props) => {
: // ProblemSession作成後の問題の改変に対応するため。
Math.min(props.problemSession.traceItemIndex, props.problem.traceItems.length - 1);
const previousTraceItemIndex = problemType === 'executionResult' ? 0 : currentTraceItemIndex - 1;
const [viewingTraceItemIndex, setViewingTraceItemIndex] = useState(previousTraceItemIndex);
const currentVariables =
problemType === 'executionResult' ? props.problem.finalVars : props.problem.traceItems[currentTraceItemIndex].vars;
const initialVariables = useMemo(
Expand All @@ -62,6 +63,11 @@ export const ProblemBody: React.FC<Props> = (props) => {
[problemType, props.problem.traceItems, previousTraceItemIndex, currentTraceItemIndex, currentVariables]
);

const [viewingTraceItemIndex, setViewingTraceItemIndex] = useState(previousTraceItemIndex);
useEffect(() => {
setViewingTraceItemIndex(previousTraceItemIndex);
}, [previousTraceItemIndex]);

const { isOpen: isAlertOpen, onClose: onAlertClose, onOpen: onAlertOpen } = useDisclosure();
const cancelRef = useRef(null);

Expand Down Expand Up @@ -147,7 +153,6 @@ export const ProblemBody: React.FC<Props> = (props) => {
} else {
await props.updateProblemSession('step', currentTraceItemIndex + 1);
openAlertDialog('正解', '正解です。次のステップに進みます。');
setViewingTraceItemIndex(currentTraceItemIndex);
}
}
break;
Expand Down Expand Up @@ -208,6 +213,13 @@ export const ProblemBody: React.FC<Props> = (props) => {
</VStack>

<SyntaxHighlighter
callerLines={
problemType === 'executionResult'
? undefined
: props.problem.traceItems[currentTraceItemIndex].callStack.map((id) =>
props.problem.callerIdToLineIndex.get(id)
)
}
code={props.problem.displayProgram}
currentFocusLine={
problemType === 'executionResult'
Expand Down Expand Up @@ -294,17 +306,36 @@ function getInitialVariables(
currentVariables: TraceItemVariable
): Record<string, string> {
let adjustedPreviousTraceItemIndex = previousTraceItemIndex;

if (problemType === 'step') {
while (
adjustedPreviousTraceItemIndex > 0 &&
traceItems[currentTraceItemIndex].depth !== traceItems[adjustedPreviousTraceItemIndex].depth
) {
if (traceItems[currentTraceItemIndex].depth > traceItems[adjustedPreviousTraceItemIndex].depth) {
return getEmptyVariables(currentVariables);
}
adjustedPreviousTraceItemIndex--;
}

if (
traceItems[currentTraceItemIndex].callStack.at(-1) !== traceItems[adjustedPreviousTraceItemIndex].callStack.at(-1)
) {
return getEmptyVariables(currentVariables);
}
}

return Object.fromEntries(
Object.entries(currentVariables)
.filter(([_, value]) => typeof value === 'number' || typeof value === 'string')
.map(([key]) => [key, traceItems[adjustedPreviousTraceItemIndex].vars[key]?.toString() ?? ''])
);
}

function getEmptyVariables(currentVariables: TraceItemVariable): Record<string, string> {
return Object.fromEntries(
Object.entries(currentVariables)
.filter(([_, value]) => typeof value === 'number' || typeof value === 'string')
.map(([key]) => [key, ''])
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { oneLight } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import { Box } from '../../../../../../../../infrastructures/useClient/chakra';

type SyntaxHighlighterProps = BoxProps & {
previousFocusLine?: number;
code: string;
programmingLanguageId: string;
callerLines?: (number | undefined)[];
currentFocusLine?: number;
previousFocusLine?: number;
programmingLanguageId: string;
};

export const SyntaxHighlighter: React.FC<SyntaxHighlighterProps> = ({
callerLines,
code,
currentFocusLine,
previousFocusLine,
Expand All @@ -33,6 +35,10 @@ export const SyntaxHighlighter: React.FC<SyntaxHighlighterProps> = ({
lineNumberStyle={{ minWidth: '1.5rem', marginRight: '2rem', paddingRight: 0 }}
lineProps={(lineNumber) => {
const style: React.CSSProperties = { padding: '0 1rem', backgroundColor: '', border: '' };
// Show dotted border for callerLines
if (callerLines?.includes(lineNumber)) {
style.border = '2px dotted #f56565'; /* red.500 */
}
// previousFocusLine と currentFocusLine が等しくなるケースがある。
if (lineNumber === previousFocusLine) {
style.backgroundColor = '#feebc8' /* orange.100 */;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import { Box, Button, Card, Heading, HStack, VStack } from '@chakra-ui/react';
import React from 'react';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const Variables: React.FC<VariablesProps> = ({ traceItemVars }) => {
<Tr key={variable.key}>
<Td fontFamily="mono">{variable.key}</Td>
<Td isNumeric fontFamily="mono">
{variable.value}
{Array.isArray(variable.value) ? variable.value.join(', ') : variable.value}
</Td>
</Tr>
))}
Expand Down
5 changes: 5 additions & 0 deletions src/problems/instantiateProblem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export type InstantiatedProblem = {
*/
sidToLineIndex: Map<number, number>;

/**
* The mapping from caller ID to line index.
*/
callerIdToLineIndex: Map<number, number>;

/**
* The variables of the final state
*/
Expand Down
Loading

0 comments on commit 944f4e8

Please sign in to comment.