Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
HarshKothari88 committed Jan 16, 2025
2 parents e005a6a + 3f47de3 commit c6fadb9
Show file tree
Hide file tree
Showing 8 changed files with 462 additions and 91 deletions.
22 changes: 21 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@
"title": "Clear Search",
"category": "Svelte Radar",
"icon": "$(clear-all)"
},
{
"command": "svelteRadar.toggleSorting",
"title": "Toggle Sorting Type",
"category": "Svelte Radar",
"icon": "$(sort-precedence)"
}
],
"viewsContainers": {
Expand Down Expand Up @@ -120,6 +126,11 @@
"command": "svelteRadar.search",
"when": "view == routesView",
"group": "navigation"
},
{
"command": "svelteRadar.toggleSorting",
"when": "view == routesView",
"group": "navigation"
}
],
"view/item/context": [
Expand Down Expand Up @@ -151,6 +162,15 @@
],
"default": "flat",
"description": "Display routes in flat or hierarchical view"
},
"svelteRadar.sortingType": {
"type": "string",
"enum": [
"natural",
"basic"
],
"default": "natural",
"description": "Route sorting type (natural: natural number sorting, basic: basic string comparison)"
}
}
}
Expand Down Expand Up @@ -191,4 +211,4 @@
"glob": "^11.0.0",
"path": "^0.12.7"
}
}
}
10 changes: 9 additions & 1 deletion src/constant/type.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export type RouteType = 'static' | 'dynamic' | 'rest' | 'optional' | 'error' | 'layout' | 'divider' | 'group' | 'matcher';
export type RouteType = 'static' | 'dynamic' | 'rest' | 'optional' | 'error' | 'layout' | 'divider' | 'group' | 'matcher' | 'spacer';

export type FileType = 'page' | 'server' | 'layout' | 'error' | 'pageServer' | 'layoutServer' | 'pageClient' | 'layoutClient';

export interface RouteColors {
static: string;
Expand All @@ -23,4 +25,10 @@ export interface RouteMatch {
export interface SegmentMatch {
remainingSegments: string[];
score: number;
}

export interface RouteFileInfo {
filePath: string;
fileType: FileType;
resetInfo: ResetInfo | null;
}
10 changes: 10 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ export function activate(context: vscode.ExtensionContext) {
vscode.window.showTextDocument(vscode.Uri.file(route.filePath));
}
}
},
{
command: 'svelteRadar.toggleSorting',
callback: async () => {
const config = vscode.workspace.getConfiguration('svelteRadar');
const currentType = config.get('sortingType', 'natural');
const newType = currentType === 'natural' ? 'basic' : 'natural';
await config.update('sortingType', newType, true);
routesProvider.refresh();
}
}
];

Expand Down
103 changes: 69 additions & 34 deletions src/models/routeItem.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as vscode from 'vscode';
import { ResetInfo, RouteType } from '../constant/type';
import { FileType, ResetInfo, RouteType } from '../constant/type';
import { basename } from 'path';

export class RouteItem extends vscode.TreeItem {
constructor(
Expand All @@ -10,7 +11,8 @@ export class RouteItem extends vscode.TreeItem {
private port: number,
public routeType: RouteType,
public isHierarchical: boolean = false,
public resetInfo: ResetInfo | null = null
public resetInfo: ResetInfo | null = null,
public fileType: FileType = 'page',
) {
super(
label,
Expand All @@ -20,36 +22,22 @@ export class RouteItem extends vscode.TreeItem {
);

// Format the label and description
if (routeType === 'divider') {
this.label = this.formatDividerLabel(label);
if (routeType === 'divider' || routeType === 'spacer') {
this.label = this.formatSpecialLabel(label, routeType);
this.description = '';
this.contextValue = 'divider';
this.tooltip = '';
this.command = undefined;
this.iconPath = undefined;
} else {
// For hierarchical view, keep the bare parameter name
if (isHierarchical) {
// Simpler description for hierarchical view
const parts: string[] = [];
if (this.resetInfo) {
parts.push(`[resets to ${this.resetInfo.displayName.replace(/[()]/g, '')}]`);
}
const matcherMatch = this.routePath.match(/\[(\w+)=(\w+)\]/);
if (matcherMatch) {
parts.push(`[${matcherMatch[2]}]`);
}
this.description = parts.join(' ');
} else {
// Flat view formatting remains the same
this.description = this.formatDescription();
}
this.label = this.formatDisplayPath(label);
this.description = this.formatDescription();
this.label = isHierarchical ? label : this.formatDisplayPath(label);

// Set icon and color
let icon = 'file';
let color = 'charts.green';

// First determine base icon and color from route type
switch (routeType) {
case 'error':
icon = 'error';
Expand Down Expand Up @@ -78,6 +66,27 @@ export class RouteItem extends vscode.TreeItem {
default:
}

const fileName = basename(filePath);
if (fileName) {
if (fileName.includes('+server.')) {
icon = 'server-process';
color = 'charts.orange';
} else if (fileName.includes('.server.')) {
icon = 'server';
color = 'charts.yellow'; // server-side files get yellow
} else if (fileName.includes('.ts') && !fileName.includes('.server.')) {
icon = 'vm';
color = 'charts.blue'; // client-side TS files get blue
} else if (fileName.includes('+layout.')) {
icon = 'layout';
color = 'charts.purple';
} else if (fileName.includes('+error.')) {
icon = 'error';
color = 'errorForeground';
}
// Regular page files will keep their route type colors
}

// ignoring the private constructor error here
// @ts-ignore
this.iconPath = new vscode.ThemeIcon(icon, new vscode.ThemeColor(color));
Expand All @@ -90,22 +99,23 @@ export class RouteItem extends vscode.TreeItem {
title: 'Open File',
arguments: [this]
};
}

// Enhanced tooltip
this.tooltip = this.getTooltipContent(routePath, routeType, resetInfo, filePath);
// Enhanced tooltip
this.tooltip = this.getTooltipContent(routePath, routeType, resetInfo, filePath, fileType);
}
}

private isGroupRoute(): boolean {
return this.routePath.includes('(') && this.routePath.includes(')');
}

private getTooltipContent(routePath: string, routeType: string, resetInfo: any, filePath: string): string {
private getTooltipContent(routePath: string, routeType: string, resetInfo: any, filePath: string, fileType: string): string {
return [
`Path: ${routePath}`,
`Type: ${routeType}`,
resetInfo ? `Resets to: ${resetInfo.displayName} layout` : '',
filePath ? `File: ${filePath}` : '',
fileType ? `Type: ${fileType}` : '',
this.isGroupRoute() ? 'Group Route' : ''
].filter(Boolean).join('\n');
}
Expand Down Expand Up @@ -142,21 +152,41 @@ export class RouteItem extends vscode.TreeItem {
layout: 'layout',
group: 'group',
divider: '',
matcher: 'matcher'
matcher: 'matcher',
spacer: ''
};

// Add page type
if (this.routeType !== 'divider') {
// Check if path contains multiple parameter types
// Determine file type based on filename first
const fileName = this.filePath ? basename(this.filePath) : '';

// Add route type only for actual pages (not for layouts, servers, etc)
if (this.routeType !== 'divider' &&
(!fileName.includes('+layout.') &&
!fileName.includes('+server.'))) {
const hasMultipleTypes = (this.routePath?.match(/\[[^\]]+\]/g) ?? []).length > 1;
const displayType = hasMultipleTypes ? 'dynamic' : typeMap[this.routeType];
parts.push(`[${displayType}]`);
}

// Add file type indicators
if (fileName) {
if (fileName.includes('+server.')) {
parts.push('[api]');
} else if (fileName.includes('+page.server.') || fileName.includes('+layout.server.')) {
parts.push('[server]');
} else if (fileName.includes('+error.')) {
parts.push('[error]');
} else if (fileName.includes('+layout.ts') || fileName.includes('+page.ts')) {
parts.push('[client]');
} else if (fileName.includes('+layout.')) {
parts.push('[layout]');
}
}

// Add group info if it's inside a group
const groupMatch = this.routePath.match(/\(([^)]+)\)/);
if (groupMatch && !this.routePath.startsWith('(')) {
parts.push(`[${groupMatch[1]} group]`);
parts.push(`[${groupMatch[1]}]`);
}

// Add matcher info if present
Expand All @@ -173,12 +203,17 @@ export class RouteItem extends vscode.TreeItem {
return parts.join(' ');
}

private formatDividerLabel(label: string): string {
// Check if it's a root level group
private formatSpecialLabel(label: string, type: RouteType): string {
console.log('formatSpecialLabel', label, type);
if (type === 'spacer') {
return '---------------'; // Simple spacer line
}

// For dividers (directory or group headers)
if (label.startsWith('(') && label.endsWith(')')) {
const groupName = label.slice(1, -1);
return `─────── ${groupName} (group) ───────`;
return `───── ${groupName} (group) ─────`;
}
return `─────── ${label} ───────`;
return `───── ${label === '/' ? 'root' : label} ─────`;
}
}
Loading

0 comments on commit c6fadb9

Please sign in to comment.