← back to mibgb65-cloud__snipxn_note

Function bodies 942 total

All specs Real LLM only Function bodies
normalizeUser function · typescript · L26-L50 (25 LOC)
snipxn_app/src/api/user.ts
function normalizeUser(raw: Record<string, unknown>): User {
  const now = new Date().toISOString();
  const createdAt = normalizeNullableString(raw.createdAt) ?? now;
  const updatedAt = normalizeNullableString(raw.updatedAt) ?? createdAt;

  return {
    id: String(raw.id ?? ''),
    email: normalizeNullableString(raw.email) ?? '',
    nickname: normalizeNullableString(raw.nickname),
    avatar: normalizeNullableString(raw.avatar),
    bio: normalizeNullableString(raw.bio),
    gender: normalizeNumber(raw.gender, 0),
    birthday: normalizeNullableString(raw.birthday),
    website: normalizeNullableString(raw.website),
    github: normalizeNullableString(raw.github),
    location: normalizeNullableString(raw.location),
    company: normalizeNullableString(raw.company),
    techStack: normalizeNullableString(raw.techStack),
    storageLimit: normalizeNumber(raw.storageLimit, 0),
    storageUsed: normalizeNumber(raw.storageUsed, 0),
    status: normalizeStatus(raw.status),
    createdA
getMe function · typescript · L52-L55 (4 LOC)
snipxn_app/src/api/user.ts
export async function getMe(): Promise<User> {
  const data = await apiClient.get<Record<string, unknown>>(USER_BASE_URL);
  return normalizeUser(data);
}
updateMe function · typescript · L57-L60 (4 LOC)
snipxn_app/src/api/user.ts
export async function updateMe(data: UpdateMeRequest): Promise<User> {
  const response = await apiClient.put<Record<string, unknown>, UpdateMeRequest>(USER_BASE_URL, data);
  return normalizeUser(response);
}
changePassword function · typescript · L62-L66 (5 LOC)
snipxn_app/src/api/user.ts
export function changePassword(password: string): Promise<void> {
  return apiClient.put<void, ChangePasswordRequest>(`${USER_BASE_URL}/password`, {
    password,
  });
}
normalizeDevice function · typescript · L68-L78 (11 LOC)
snipxn_app/src/api/user.ts
function normalizeDevice(raw: Record<string, unknown>): UserDevice {
  return {
    id: String(raw.id ?? raw.deviceId ?? ''),
    deviceName: normalizeNullableString(raw.deviceName),
    deviceId: String(raw.deviceId ?? ''),
    lastLoginIp: normalizeNullableString(raw.lastLoginIp),
    lastLoginAt: normalizeNullableString(raw.lastLoginAt) ?? new Date().toISOString(),
    isRevoked: raw.isRevoked === true,
    createdAt: normalizeNullableString(raw.createdAt) ?? new Date().toISOString(),
  };
}
getDevices function · typescript · L80-L83 (4 LOC)
snipxn_app/src/api/user.ts
export async function getDevices(): Promise<UserDevice[]> {
  const data = await apiClient.get<Record<string, unknown>[]>(`${USER_BASE_URL}/devices`);
  return Array.isArray(data) ? data.map(normalizeDevice) : [];
}
revokeDevice function · typescript · L85-L87 (3 LOC)
snipxn_app/src/api/user.ts
export function revokeDevice(deviceId: string): Promise<void> {
  return apiClient.delete<void>(`${USER_BASE_URL}/devices/${deviceId}`);
}
Source: Repobility analyzer · https://repobility.com
revokeOtherDevices function · typescript · L89-L91 (3 LOC)
snipxn_app/src/api/user.ts
export function revokeOtherDevices(): Promise<void> {
  return apiClient.delete<void>(`${USER_BASE_URL}/devices`);
}
getLinkedAccounts function · typescript · L93-L95 (3 LOC)
snipxn_app/src/api/user.ts
export function getLinkedAccounts(): Promise<LinkedAccount[]> {
  return apiClient.get<LinkedAccount[]>(`${USER_BASE_URL}/linked-accounts`);
}
bindGithub function · typescript · L97-L105 (9 LOC)
snipxn_app/src/api/user.ts
export function bindGithub(code: string, redirectUri: string): Promise<void> {
  return apiClient.post<void, OAuthBindRequest>(
    `${USER_BASE_URL}/linked-accounts/github`,
    {
      code,
      redirectUri,
    },
  );
}
bindGoogle function · typescript · L107-L115 (9 LOC)
snipxn_app/src/api/user.ts
export function bindGoogle(code: string, redirectUri: string): Promise<void> {
  return apiClient.post<void, OAuthBindRequest>(
    `${USER_BASE_URL}/linked-accounts/google`,
    {
      code,
      redirectUri,
    },
  );
}
unlinkAccount function · typescript · L117-L121 (5 LOC)
snipxn_app/src/api/user.ts
export function unlinkAccount(
  identityType: LinkedAccount['identityType'],
): Promise<void> {
  return apiClient.delete<void>(`${USER_BASE_URL}/linked-accounts/${identityType}`);
}
AdaptiveLayout function · typescript · L21-L71 (51 LOC)
snipxn_app/src/components/common/AdaptiveLayout.tsx
export function AdaptiveLayout({
  renderSidebar,
  renderList,
  renderContent,
  sidebarWidth = DEFAULT_SIDEBAR_WIDTH,
  listWidth = DEFAULT_LIST_WIDTH,
}: AdaptiveLayoutProps) {
  const { showSidebar, showMasterDetail } = useDeviceType();
  const { palette } = useAppTheme();
  const shouldRenderSidebarPane = showMasterDetail && sidebarWidth > 0;

  if (!showSidebar) {
    return (
      <Animated.View layout={APP_LAYOUT_TRANSITION} style={{ flex: 1, minWidth: 0 }}>
        {renderList()}
      </Animated.View>
    );
  }

  if (!showMasterDetail || !shouldRenderSidebarPane) {
    return (
      <MasterDetail
        masterWidth={listWidth}
        renderMaster={renderList}
        renderDetail={renderContent}
        showDetail
      />
    );
  }

  return (
    <Animated.View
      layout={APP_LAYOUT_TRANSITION}
      style={{ flex: 1, minWidth: 0, flexDirection: 'row', backgroundColor: palette.canvas }}>
      <Animated.View
        layout={APP_LAYOUT_TRANSITION}
        style={{
getPanelBackground function · typescript · L21-L38 (18 LOC)
snipxn_app/src/components/common/AppChrome.tsx
function getPanelBackground(
  variant: NonNullable<GlassPanelProps['variant']>,
  palette: ReturnType<typeof useAppTheme>['palette'],
) {
  if (variant === 'strong') {
    return palette.panelStrong;
  }

  if (variant === 'subtle') {
    return palette.panelSubtle;
  }

  if (variant === 'inset') {
    return palette.panelInset;
  }

  return palette.panelRaised;
}
AppCanvas function · typescript · L40-L113 (74 LOC)
snipxn_app/src/components/common/AppChrome.tsx
export function AppCanvas({
  children,
  className = 'flex-1',
  style,
  decorative = true,
}: CanvasProps) {
  const { isTablet, palette } = useAppTheme();

  return (
    <View className={className} style={[{ backgroundColor: palette.canvas }, style]}>
      {decorative ? (
        <View pointerEvents="none" style={StyleSheet.absoluteFill}>
          <View
            style={[
              styles.blob,
              {
                width: isTablet ? 320 : 240,
                height: isTablet ? 320 : 240,
                top: isTablet ? -84 : -72,
                left: isTablet ? -88 : -64,
                backgroundColor: palette.backdropPrimary,
              },
            ]}
          />
          <View
            style={[
              styles.blob,
              {
                width: isTablet ? 280 : 210,
                height: isTablet ? 280 : 210,
                top: isTablet ? -32 : -20,
                right: isTablet ? -60 : -40,
                backgroundColor: 
Repobility · open methodology · https://repobility.com/research/
GlassPanel function · typescript · L115-L144 (30 LOC)
snipxn_app/src/components/common/AppChrome.tsx
export function GlassPanel({
  children,
  className = '',
  style,
  variant = 'raised',
  highlight = null,
}: GlassPanelProps) {
  const { theme, palette } = useAppTheme();
  const shadowOpacity =
    variant === 'raised' ? (theme === 'dark' ? 0.26 : 0.12) : theme === 'dark' ? 0.18 : 0.08;

  return (
    <View
      className={`overflow-hidden rounded-[12px] border ${className}`.trim()}
      style={[
        {
          borderColor: highlight ? withAlpha(highlight, 0.22) : palette.border,
          backgroundColor: getPanelBackground(variant, palette),
          shadowColor: palette.shadow,
          shadowOpacity,
          shadowRadius: variant === 'raised' ? 18 : 12,
          shadowOffset: { width: 0, height: variant === 'raised' ? 12 : 8 },
          elevation: variant === 'raised' ? 10 : 5,
        },
        style,
      ]}>
      {children}
    </View>
  );
}
IconBadge function · typescript · L146-L177 (32 LOC)
snipxn_app/src/components/common/AppChrome.tsx
export function IconBadge({
  icon,
  size = 46,
  iconSize = 20,
  color,
  backgroundColor,
  round = false,
}: {
  icon: AppIconName;
  size?: number;
  iconSize?: number;
  color?: string;
  backgroundColor?: string;
  round?: boolean;
}) {
  const { palette } = useAppTheme();
  const resolvedColor = color ?? palette.primary;
  const resolvedBackgroundColor = backgroundColor ?? palette.primarySoft;

  return (
    <View
      className="items-center justify-center"
      style={{
        width: size,
        height: size,
        borderRadius: round ? size / 2 : Math.max(8, size * 0.22),
        backgroundColor: resolvedBackgroundColor,
      }}>
      <AppIcon color={resolvedColor} name={icon} size={iconSize} />
    </View>
  );
}
SectionEyebrow function · typescript · L179-L187 (9 LOC)
snipxn_app/src/components/common/AppChrome.tsx
export function SectionEyebrow({ children }: { children: ReactNode }) {
  const { palette, typography } = useAppTheme();

  return (
    <Text className={typography.caption} style={{ color: palette.primary }}>
      {children}
    </Text>
  );
}
MetricPill function · typescript · L189-L211 (23 LOC)
snipxn_app/src/components/common/AppChrome.tsx
export function MetricPill({
  label,
  tone = 'default',
}: {
  label: string;
  tone?: 'default' | 'accent' | 'cta';
}) {
  const { palette, typography } = useAppTheme();
  const toneColor = tone === 'accent' ? palette.accent : tone === 'cta' ? palette.cta : palette.textMuted;

  return (
    <View
      className="rounded-full border px-3.5 py-2"
      style={{
        borderColor: withAlpha(toneColor, 0.16),
        backgroundColor: tone === 'default' ? palette.panelInset : withAlpha(toneColor, 0.12),
      }}>
      <Text className={typography.caption} style={{ color: tone === 'default' ? palette.textMuted : toneColor }}>
        {label}
      </Text>
    </View>
  );
}
MetricCard function · typescript · L213-L232 (20 LOC)
snipxn_app/src/components/common/AppChrome.tsx
export function MetricCard({
  value,
  label,
}: {
  value: string | number;
  label: string;
}) {
  const { palette, typography } = useAppTheme();

  return (
    <GlassPanel className="min-w-[84px] px-3.5 py-3" variant="inset">
      <Text className={typography.h3} style={{ color: palette.text }}>
        {value}
      </Text>
      <Text className={typography.caption} style={{ color: palette.textSoft }}>
        {label}
      </Text>
    </GlassPanel>
  );
}
AppIcon function · typescript · L60-L397 (338 LOC)
snipxn_app/src/components/common/AppIcon.tsx
export function AppIcon({
  name,
  size = 20,
  color = 'currentColor',
  strokeWidth = 1.9,
  filled = false,
}: AppIconProps) {
  const commonProps = {
    fill: 'none',
    stroke: color,
    strokeLinecap: 'round' as const,
    strokeLinejoin: 'round' as const,
    strokeWidth,
  };

  const effectiveFilled =
    filled || name === 'star-filled' || name === 'heart-filled' || name === 'bookmark-filled';

  return (
    <Svg height={size} viewBox="0 0 24 24" width={size}>
      {name === 'search' ? (
        <>
          <Circle cx="11" cy="11" r="7" {...commonProps} />
          <Line x1="20" x2="16.65" y1="20" y2="16.65" {...commonProps} />
        </>
      ) : null}

      {name === 'plus' ? (
        <>
          <Line x1="12" x2="12" y1="5" y2="19" {...commonProps} />
          <Line x1="5" x2="19" y1="12" y2="12" {...commonProps} />
        </>
      ) : null}

      {name === 'sparkles' ? (
        <>
          <Path d="M12 3l1.4 4.1L17.5 8.5l-4.1 1.4L12 14l-1.4-4.1L6.5 8.5l
EllipseFallback function · typescript · L399-L420 (22 LOC)
snipxn_app/src/components/common/AppIcon.tsx
function EllipseFallback({
  color,
  strokeWidth,
  y,
}: {
  color: string;
  strokeWidth: number;
  y: string;
}) {
  return (
    <>
      <Path
        d={`M5 ${y}c0 1.7 3.1 3 7 3s7-1.3 7-3-3.1-3-7-3-7 1.3-7 3z`}
        fill="none"
        stroke={color}
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth={strokeWidth}
      />
    </>
  );
}
MotionPressable function · typescript · L55-L96 (42 LOC)
snipxn_app/src/components/common/AppMotion.tsx
export function MotionPressable({
  children,
  className,
  pressedScale = 0.975,
  style,
  onPressIn,
  onPressOut,
  ...props
}: MotionPressableProps) {
  const scale = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => {
    'worklet';

    return {
      transform: [{ scale: scale.value }],
    };
  });

  const handlePressIn = (event: GestureResponderEvent) => {
    scale.value = withSpring(pressedScale, PRESS_SPRING_CONFIG);
    onPressIn?.(event);
  };

  const handlePressOut = (event: GestureResponderEvent) => {
    scale.value = withSpring(1, PRESS_SPRING_CONFIG);
    onPressOut?.(event);
  };

  return (
    <Animated.View style={animatedStyle}>
      <Pressable
        {...props}
        className={className}
        onPressIn={handlePressIn}
        onPressOut={handlePressOut}
        style={style}>
        {children}
      </Pressable>
    </Animated.View>
  );
}
Repobility (the analyzer behind this table) · https://repobility.com
MasterDetail function · typescript · L19-L55 (37 LOC)
snipxn_app/src/components/common/MasterDetail.tsx
export function MasterDetail({
  masterWidth = DEFAULT_MASTER_WIDTH,
  renderMaster,
  renderDetail,
  showDetail,
}: MasterDetailProps) {
  const { showMasterDetail, showSidebar } = useDeviceType();
  const { palette } = useAppTheme();

  if (!showSidebar || !showDetail) {
    return (
      <Animated.View layout={APP_LAYOUT_TRANSITION} style={{ flex: 1, minWidth: 0 }}>
        {renderMaster()}
      </Animated.View>
    );
  }

  const resolvedMasterWidth = showMasterDetail
    ? masterWidth
    : Math.min(masterWidth, NARROW_MASTER_MAX_WIDTH);

  return (
    <Animated.View
      layout={APP_LAYOUT_TRANSITION}
      style={{ flex: 1, minWidth: 0, flexDirection: 'row', backgroundColor: palette.canvas }}>
      <Animated.View
        layout={APP_LAYOUT_TRANSITION}
        style={{ minWidth: 0, flexShrink: 0, width: resolvedMasterWidth }}>
        {renderMaster()}
      </Animated.View>
      <Animated.View layout={APP_LAYOUT_TRANSITION} style={{ width: 1, backgroundColor: palette.bord
CommentItem function · typescript · L142-L241 (100 LOC)
snipxn_app/src/components/community/CommentItem.tsx
export function CommentItem({
  comment,
  replies,
  currentUserId,
  isLoadingReplies = false,
  onPressUser,
  onReply,
  onDelete,
  onToggleLike,
  onLoadReplies,
}: CommentItemProps) {
  const { typography } = useAppTheme();
  const { isEnglish, t } = useI18n();
  const [repliesVisible, setRepliesVisible] = useState(false);
  const [showAllReplies, setShowAllReplies] = useState(false);

  const totalReplies = Math.max(comment.replyCount ?? 0, replies.length);
  const visibleReplies = useMemo(
    () => (showAllReplies ? replies : replies.slice(0, MAX_VISIBLE_REPLIES)),
    [replies, showAllReplies],
  );
  const hasMoreReplies = totalReplies > MAX_VISIBLE_REPLIES || replies.length > MAX_VISIBLE_REPLIES;

  const handleExpandAll = () => {
    if (totalReplies > replies.length) {
      onLoadReplies(comment.id);
    }
    setShowAllReplies(true);
  };

  const handleCollapseAll = () => {
    setRepliesVisible(false);
    setShowAllReplies(false);
  };

  const handleExpandReplies =
CommentSection function · typescript · L23-L249 (227 LOC)
snipxn_app/src/components/community/CommentSection.tsx
export function CommentSection({
  postId,
  headerComponent = null,
  onPressUser,
  onReply,
}: CommentSectionProps) {
  const { palette, typography } = useAppTheme();
  const { t } = useI18n();
  const currentUserId = useAuthStore(state => state.user?.id ?? null);
  const { comments, loading, fetchComments, fetchReplies, deleteComment, likeComment, unlikeComment } = useCommunityStore(useShallow(state => ({
    comments: state.comments,
    loading: state.loading,
    fetchComments: state.fetchComments,
    fetchReplies: state.fetchReplies,
    deleteComment: state.deleteComment,
    likeComment: state.likeComment,
    unlikeComment: state.unlikeComment,
  })));

  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [loadingReplyId, setLoadingReplyId] = useState<string | null>(null);
  const [feedback, setFeedback] = useState<string | null>(null);

  const topLevelComments = useMemo(
   
CommunityActionPill function · typescript · L32-L66 (35 LOC)
snipxn_app/src/components/community/CommunityActionPill.tsx
export function CommunityActionPill({
  icon,
  label,
  active = false,
  activeIcon,
  color,
  disabled = false,
  size = 'sm',
  onPress,
}: CommunityActionPillProps) {
  const { palette, typography } = useAppTheme();
  const iconName = active && activeIcon ? activeIcon : icon;
  const tintColor = active ? color : palette.textMuted;

  return (
    <MotionPressable
      accessibilityRole="button"
      className={`rounded-full border ${SIZE_CLASS_NAME[size]}`}
      disabled={disabled}
      pressedScale={disabled ? 1 : 0.96}
      onPress={onPress}
      style={{
        borderColor: active ? withAlpha(color, 0.28) : palette.border,
        backgroundColor: active ? withAlpha(color, 0.12) : palette.surfaceAlt,
        opacity: disabled ? 0.6 : 1,
      }}>
      <View className="flex-row items-center gap-1.5">
        <AppIcon color={tintColor} name={iconName} size={ICON_SIZE[size]} />
        <Text className={`${typography.bodySmall} font-medium`} style={{ color: tintColor }}>
 
resolveCommunityAssetUrl function · typescript · L9-L16 (8 LOC)
snipxn_app/src/components/community/communityUtils.ts
export function resolveCommunityAssetUrl(value: string | null): string | null {
  if (!value) {
    return null;
  }

  if (/^https?:\/\//i.test(value)) {
    return value;
  }
getUserAvatarFallback function · typescript · L22-L25 (4 LOC)
snipxn_app/src/components/community/communityUtils.ts
export function getUserAvatarFallback(name: string | null | undefined): string {
  const source = name?.trim() || 'S';
  return source.slice(0, 1).toUpperCase();
}
getCommunityErrorMessage function · typescript · L27-L38 (12 LOC)
snipxn_app/src/components/community/communityUtils.ts
export function getCommunityErrorMessage(error: unknown, fallback: string): string {
  if (
    typeof error === 'object' &&
    error !== null &&
    'message' in error &&
    typeof error.message === 'string'
  ) {
    return translateLiteral(error.message);
  }

  return fallback;
}
getRuntimeEnv function · typescript · L40-L43 (4 LOC)
snipxn_app/src/components/community/communityUtils.ts
function getRuntimeEnv(): Record<string, string | undefined> {
  const runtime = globalThis as typeof globalThis & { process?: RuntimeProcess };
  return runtime.process?.env ?? {};
}
Same scanner, your repo: https://repobility.com — Repobility
resolveWebBaseUrl function · typescript · L45-L55 (11 LOC)
snipxn_app/src/components/community/communityUtils.ts
function resolveWebBaseUrl(): string {
  const env = getRuntimeEnv();
  const configuredBaseUrl =
    env.SNIPXN_WEB_BASE_URL ?? env.WEB_BASE_URL ?? env.REACT_NATIVE_WEB_BASE_URL;

  if (configuredBaseUrl && configuredBaseUrl.trim().length > 0) {
    return configuredBaseUrl.replace(/\/+$/, '');
  }

  return API_BASE_URL.replace(/\/api\/v1\/?$/, '');
}
buildCommunityShareUrl function · typescript · L57-L59 (3 LOC)
snipxn_app/src/components/community/communityUtils.ts
export function buildCommunityShareUrl(shareToken: string): string {
  return `${resolveWebBaseUrl()}/share/${shareToken}`;
}
PostCard function · typescript · L22-L133 (112 LOC)
snipxn_app/src/components/community/PostCard.tsx
export function PostCard({
  post,
  onPress,
  onPressAuthor,
  onPressLike,
  onPressCollect,
  onPressComment,
}: PostCardProps) {
  const { palette, typography } = useAppTheme();
  const { isEnglish, t } = useI18n();
  const avatarUri = resolveCommunityAssetUrl(post.authorAvatar);
  const visibleTags = post.tags.filter(tag => tag.trim().length > 0).slice(0, 3);
  const extraTagCount = Math.max(post.tags.length - visibleTags.length, 0);

  return (
        <View
          className="overflow-hidden rounded-[20px] border px-4 py-4"
          style={{
            borderColor: palette.border,
            backgroundColor: palette.surface,
            shadowColor: palette.shadow,
            shadowOpacity: 0.1,
            shadowRadius: 14,
            shadowOffset: { width: 0, height: 10 },
            elevation: 6,
          }}>
          <View className="flex-row items-center justify-between gap-3">
          <Pressable
            accessibilityRole="button"
            className="min
getErrorMessage function · typescript · L26-L37 (12 LOC)
snipxn_app/src/components/note/AiPanel.tsx
function getErrorMessage(error: unknown, fallback: string): string {
  if (
    typeof error === 'object' &&
    error !== null &&
    'message' in error &&
    typeof error.message === 'string'
  ) {
    return error.message;
  }

  return fallback;
}
AiPanel function · typescript · L39-L413 (375 LOC)
snipxn_app/src/components/note/AiPanel.tsx
export function AiPanel({
  isOpen,
  currentContent,
  currentLanguage,
  onOpenChange,
  onInsertGenerated,
  onBusyChange,
  inline,
}: AiPanelProps) {
  const { screenHeight } = useDeviceType();
  const { palette, theme, typography } = useAppTheme();

  const [activeTab, setActiveTab] = useState<AiTab>('review');
  const [reviewFocus, setReviewFocus] = useState('请从潜在 bug、边界条件、可读性和性能优化角度审查当前代码。');
  const [reviewLoading, setReviewLoading] = useState(false);
  const [reviewResult, setReviewResult] = useState<AiResponse | null>(null);
  const [reviewError, setReviewError] = useState<string | null>(null);
  const [generatePrompt, setGeneratePrompt] = useState('');
  const [generateLoading, setGenerateLoading] = useState(false);
  const [generatedResult, setGeneratedResult] = useState<AiResponse | null>(null);
  const [generateError, setGenerateError] = useState<string | null>(null);
  const [fontSize, setFontSize] = useState<number>(DEFAULT_CODE_FONT_SIZE);

  useEffect(() => {
    let
normalizeRunnerLanguage function · typescript · L32-L34 (3 LOC)
snipxn_app/src/components/note/CodeBlockRunner.tsx
function normalizeRunnerLanguage(language: string): string | null {
  return RUNNABLE_LANGUAGE_MAP[language.trim().toLowerCase()] ?? null;
}
getErrorMessage function · typescript · L36-L47 (12 LOC)
snipxn_app/src/components/note/CodeBlockRunner.tsx
function getErrorMessage(error: unknown, fallback: string): string {
  if (
    typeof error === 'object' &&
    error !== null &&
    'message' in error &&
    typeof error.message === 'string'
  ) {
    return error.message;
  }

  return fallback;
}
pickNumber function · typescript · L49-L57 (9 LOC)
snipxn_app/src/components/note/CodeBlockRunner.tsx
function pickNumber(source: RunCodeResponse, keys: string[]): number | null {
  for (const key of keys) {
    const value = source[key];
    if (typeof value === 'number' && Number.isFinite(value)) {
      return value;
    }
  }
  return null;
}
Source: Repobility analyzer · https://repobility.com
pickString function · typescript · L59-L67 (9 LOC)
snipxn_app/src/components/note/CodeBlockRunner.tsx
function pickString(source: RunCodeResponse, keys: string[]): string | null {
  for (const key of keys) {
    const value = source[key];
    if (typeof value === 'string' && value.trim().length > 0) {
      return value.trim();
    }
  }
  return null;
}
formatBytes function · typescript · L69-L84 (16 LOC)
snipxn_app/src/components/note/CodeBlockRunner.tsx
function formatBytes(bytes: number): string {
  if (bytes < 1024) {
    return `${bytes} B`;
  }

  const units = ['KB', 'MB', 'GB'];
  let value = bytes / 1024;
  let unitIndex = 0;

  while (value >= 1024 && unitIndex < units.length - 1) {
    value /= 1024;
    unitIndex += 1;
  }

  return `${value.toFixed(value >= 100 ? 0 : 1)} ${units[unitIndex]}`;
}
formatDuration function · typescript · L86-L103 (18 LOC)
snipxn_app/src/components/note/CodeBlockRunner.tsx
function formatDuration(response: RunCodeResponse | null): string {
  if (!response) {
    return '--';
  }

  const numericDuration = pickNumber(response, [
    'executionTimeMs',
    'timeMs',
    'durationMs',
    'runtimeMs',
  ]);

  if (numericDuration !== null) {
    return `${numericDuration} ms`;
  }

  return pickString(response, ['executionTime', 'duration', 'runtime']) ?? '--';
}
formatMemory function · typescript · L105-L126 (22 LOC)
snipxn_app/src/components/note/CodeBlockRunner.tsx
function formatMemory(response: RunCodeResponse | null): string {
  if (!response) {
    return '--';
  }

  const memoryBytes = pickNumber(response, ['memoryBytes', 'memoryUsedBytes']);
  if (memoryBytes !== null) {
    return formatBytes(memoryBytes);
  }

  const memoryKb = pickNumber(response, ['memoryKb', 'memoryKB', 'memoryUsedKb']);
  if (memoryKb !== null) {
    return `${memoryKb} KB`;
  }

  const memoryMb = pickNumber(response, ['memoryMb', 'memoryMB', 'memoryUsedMb']);
  if (memoryMb !== null) {
    return `${memoryMb} MB`;
  }

  return pickString(response, ['memory', 'memoryUsed']) ?? '--';
}
resolveRunnerStatus function · typescript · L128-L144 (17 LOC)
snipxn_app/src/components/note/CodeBlockRunner.tsx
function resolveRunnerStatus(response: RunCodeResponse): RunnerStatus {
  const status = typeof response.status === 'string' ? response.status.toLowerCase() : '';

  if (status.includes('timeout')) {
    return 'timeout';
  }

  if (status.includes('error') || status.includes('fail')) {
    return 'error';
  }

  if (typeof response.stderr === 'string' && response.stderr.trim().length > 0) {
    return 'error';
  }

  return 'success';
}
CodeBlockRunner function · typescript · L154-L442 (289 LOC)
snipxn_app/src/components/note/CodeBlockRunner.tsx
export function CodeBlockRunner({
  content,
  documentLanguage,
  onClose,
  onScrollToLine,
  onStatusChange,
}: CodeBlockRunnerProps) {
  const { palette, typography } = useAppTheme();
  const { t } = useI18n();

  const blocks = useMemo(
    () => extractCodeBlocks(content, documentLanguage),
    [content, documentLanguage],
  );

  const [currentIndex, setCurrentIndex] = useState(0);
  const [status, setStatus] = useState<RunnerStatus>('idle');
  const [result, setResult] = useState<RunCodeResponse | null>(null);
  const [fontSize, setFontSize] = useState<number>(DEFAULT_CODE_FONT_SIZE);

  useEffect(() => {
    let isMounted = true;
    void getStoredCodeFontSize().then(value => {
      if (isMounted) {
        setFontSize(value);
      }
    });
    return () => {
      isMounted = false;
    };
  }, []);

  useEffect(() => {
    onStatusChange?.(status);
  }, [onStatusChange, status]);

  // Clamp index if blocks change
  useEffect(() => {
    if (blocks.length === 0) {
      s
getErrorMessage function · typescript · L67-L78 (12 LOC)
snipxn_app/src/components/note/CodeEditor.tsx
function getErrorMessage(error: unknown, fallback: string): string {
  if (
    typeof error === 'object' &&
    error !== null &&
    'message' in error &&
    typeof error.message === 'string'
  ) {
    return translateLiteral(error.message);
  }

  return fallback;
}
normalizeLanguage function · typescript · L80-L82 (3 LOC)
snipxn_app/src/components/note/CodeEditor.tsx
function normalizeLanguage(language: string): string {
  return language.trim().length > 0 ? language.trim() : 'markdown';
}
Repobility · open methodology · https://repobility.com/research/
createBootScript function · typescript · L84-L92 (9 LOC)
snipxn_app/src/components/note/CodeEditor.tsx
function createBootScript(config: {
  content: string;
  language: string;
  readOnly: boolean;
  theme: EditorTheme;
  fontSize: number;
}): string {
  return `window.__SNIPXN_EDITOR_BOOT__ = ${JSON.stringify(config)}; true;`;
}
FallbackCodeEditor function · typescript · L94-L121 (28 LOC)
snipxn_app/src/components/note/CodeEditor.tsx
function FallbackCodeEditor({
  content,
  readOnly = false,
  onContentChange,
}: CodeEditorProps) {
  const { palette, typography } = useAppTheme();
  const { isTablet } = useDeviceType();
  const { t } = useI18n();

  return (
    <GlassPanel className="flex-1 gap-3 px-4 py-4" variant="inset">
      <Text className={typography.bodySmall} style={{ color: palette.textSoft }}>
        {t('当前使用兼容编辑模式。')}
      </Text>
      <TextInput
        autoCapitalize="none"
        className={`${typography.code} flex-1`}
        editable={!readOnly}
        multiline
        onChangeText={onContentChange}
        placeholder={t('开始编写 Markdown 或代码片段...')}
        placeholderTextColor={palette.placeholder}
        style={{ color: palette.text, fontSize: isTablet ? 16 : 14, textAlignVertical: 'top' }}
        value={content}
      />
    </GlassPanel>
  );
}
getErrorMessage function · typescript · L45-L56 (12 LOC)
snipxn_app/src/components/note/CodeRunnerPanel.tsx
function getErrorMessage(error: unknown, fallback: string): string {
  if (
    typeof error === 'object' &&
    error !== null &&
    'message' in error &&
    typeof error.message === 'string'
  ) {
    return error.message;
  }

  return fallback;
}
‹ prevpage 3 / 19next ›