diff --git a/mobile/design/mobile.pen b/mobile/design/mobile.pen index de69a3d..5300caf 100644 --- a/mobile/design/mobile.pen +++ b/mobile/design/mobile.pen @@ -12117,31 +12117,6 @@ "gap": 10, "alignItems": "center", "children": [ - { - "type": "frame", - "id": "fRG17", - "width": "fill_container", - "height": 44, - "fill": "$surface-card", - "cornerRadius": "$radius-control", - "stroke": { - "thickness": 1, - "fill": "$border-strong" - }, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "NDKmy", - "fill": "$font-primary", - "content": "格式化", - "fontFamily": "Inter", - "fontSize": 14, - "fontWeight": "600" - } - ] - }, { "type": "frame", "id": "z1k2o", @@ -13190,6417 +13165,6 @@ } ] }, - { - "type": "frame", - "id": "AGTU4", - "x": 6436, - "y": 904, - "name": "代码编辑页(AI 助手)", - "clip": true, - "width": 390, - "height": 1087, - "fill": "$surface", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "Y7Ozw8", - "width": "fill_container", - "height": 62, - "padding": [ - 0, - 20 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "GQYqQ", - "fill": "$font-primary", - "content": "9:41", - "fontFamily": "Inter", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "frame", - "id": "kfPTb", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "xNuQS", - "width": 16, - "height": 16, - "iconFontName": "signal", - "iconFontFamily": "lucide", - "fill": "$font-primary" - }, - { - "type": "icon_font", - "id": "hHHoZ", - "width": 16, - "height": 16, - "iconFontName": "wifi", - "iconFontFamily": "lucide", - "fill": "$font-primary" - }, - { - "type": "icon_font", - "id": "zCMRZ", - "width": 22, - "height": 16, - "iconFontName": "battery-full", - "iconFontFamily": "lucide", - "fill": "$font-primary" - } - ] - } - ] - }, - { - "type": "frame", - "id": "oeHxZ", - "width": "fill_container", - "height": 54, - "padding": [ - 0, - 16 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "d0sfo2", - "gap": 10, - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "FA4Bq", - "width": 22, - "height": 22, - "iconFontName": "chevron-left", - "iconFontFamily": "lucide", - "fill": "$font-primary" - }, - { - "type": "frame", - "id": "e0aYxX", - "layout": "vertical", - "gap": 1, - "children": [ - { - "type": "frame", - "id": "Vmzzt", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "GUAD5", - "fill": "$font-primary", - "content": "nginx.conf", - "fontFamily": "Inter", - "fontSize": 15, - "fontWeight": "600" - }, - { - "type": "ellipse", - "id": "b53Bsc", - "fill": "$warning", - "width": 6, - "height": 6 - } - ] - }, - { - "type": "text", - "id": "rQWvF", - "fill": "$font-muted", - "content": "/etc/nginx · 已修改", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "A1b0bm", - "gap": 10, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "B7qoB", - "fill": "$accent-soft", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$accent" - }, - "gap": 5, - "padding": [ - 5, - 10 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "MIbys", - "width": 12, - "height": 12, - "iconFontName": "sparkles", - "iconFontFamily": "lucide", - "fill": "$primary" - }, - { - "type": "text", - "id": "ToPdb", - "fill": "$primary", - "content": "AI", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "700" - } - ] - }, - { - "type": "icon_font", - "id": "D79ZyS", - "width": 20, - "height": 20, - "iconFontName": "ellipsis", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - } - ] - } - ] - }, - { - "type": "frame", - "id": "i5DmX", - "width": "fill_container", - "height": 380, - "fill": "$surface-inverse", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "IG2Ff", - "width": "fill_container", - "height": "fill_container", - "children": [ - { - "type": "frame", - "id": "L9b80j", - "width": 36, - "height": "fill_container", - "layout": "vertical", - "gap": 4, - "padding": [ - 10, - 6, - 10, - 8 - ], - "alignItems": "end", - "children": [ - { - "type": "text", - "id": "BFoBH", - "fill": "#6B7280", - "content": "1", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "s4FbY", - "fill": "#6B7280", - "content": "2", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "FMTrV", - "fill": "#6B7280", - "content": "3", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "lGrcZ", - "fill": "#6B7280", - "content": "4", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "SeM8O", - "fill": "#6B7280", - "content": "5", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "UllDs", - "fill": "#6B7280", - "content": "6", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "u6KyA", - "fill": "$accent", - "content": "7", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "fCB0J", - "fill": "$accent", - "content": "8", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "FDuvb", - "fill": "$accent", - "content": "9", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "ajjew", - "fill": "$accent", - "content": "10", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "O38gwk", - "fill": "#6B7280", - "content": "11", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "uWm99", - "fill": "#6B7280", - "content": "12", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "z642n5", - "fill": "#6B7280", - "content": "13", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "e5EKxV", - "fill": "#6B7280", - "content": "14", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "p32MHD", - "fill": "#6B7280", - "content": "15", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "h5oD4", - "fill": "#6B7280", - "content": "16", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "F4lFf", - "width": "fill_container", - "height": "fill_container", - "layout": "vertical", - "gap": 4, - "padding": [ - 10, - 12, - 10, - 8 - ], - "children": [ - { - "type": "frame", - "id": "nDM1D", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "aytNk", - "fill": "#569CD6", - "content": "worker_processes", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "nF7hU", - "fill": "#D4D4D4", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "kUEZ5", - "fill": "#B5CEA8", - "content": "1", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "kwnlw", - "fill": "#D4D4D4", - "content": ";", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "ZZQE4", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center" - }, - { - "type": "frame", - "id": "s1wha", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "Zm3Ku", - "fill": "#569CD6", - "content": "events", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "Nls4L", - "fill": "#D4D4D4", - "content": " {", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "fnGFX", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "Evwi9", - "fill": "#569CD6", - "content": " worker_connections", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "fxoey", - "fill": "#D4D4D4", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "gkAP1", - "fill": "#B5CEA8", - "content": "1024", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "qB0Gi", - "fill": "#D4D4D4", - "content": ";", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "mYEf2", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "wwNcm", - "fill": "#D4D4D4", - "content": "}", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "rQtRi", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center" - }, - { - "type": "frame", - "id": "R4rvB", - "width": "fill_container", - "height": 16, - "fill": "#E5B33A14", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "g2feSG", - "fill": "#569CD6", - "content": "http", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "q6Cfzt", - "fill": "#D4D4D4", - "content": " {", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "E8dENs", - "width": "fill_container", - "height": 16, - "fill": "#E5B33A14", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "RWCKW", - "fill": "#569CD6", - "content": " server", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "oy9dG", - "fill": "#D4D4D4", - "content": " {", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "FtbDX", - "width": "fill_container", - "height": 16, - "fill": "#E5B33A14", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "EYH34", - "fill": "#569CD6", - "content": " listen", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "v8DsP", - "fill": "#D4D4D4", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "YDi07", - "fill": "#B5CEA8", - "content": "80", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "y2GXL", - "fill": "#D4D4D4", - "content": ";", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "Cf1wc", - "width": "fill_container", - "height": 16, - "fill": "#E5B33A14", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "HlchQ", - "fill": "#569CD6", - "content": " server_name", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "GKelJ", - "fill": "#D4D4D4", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "P8rzrF", - "fill": "#CE9178", - "content": "easynode.local", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "OD6CF", - "fill": "#D4D4D4", - "content": ";", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "h9GM2j", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center" - }, - { - "type": "frame", - "id": "D9dZi", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "r69GUu", - "fill": "#569CD6", - "content": " location ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "ypyZ8", - "fill": "#CE9178", - "content": "/", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "Kmvu7", - "fill": "#D4D4D4", - "content": " {", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "Zs1zr", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "v49ff", - "fill": "#569CD6", - "content": " root", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "hgT7g", - "fill": "#D4D4D4", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "g8Xyw5", - "fill": "#CE9178", - "content": "/usr/share/nginx/html", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "z1y6RK", - "fill": "#D4D4D4", - "content": ";", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "yU789", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "NvA6f", - "fill": "#D4D4D4", - "content": " }", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "NtFqi", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "O9Scr", - "fill": "#D4D4D4", - "content": " }", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "DBnIZ", - "width": "fill_container", - "height": 16, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "T5uWmL", - "fill": "#D4D4D4", - "content": "}", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "L1EAU", - "layoutPosition": "absolute", - "x": 36, - "y": 168, - "width": 326, - "fill": "#1F2937F2", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "$accent" - }, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#00000066", - "offset": { - "x": 0, - "y": 6 - }, - "blur": 20 - }, - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "H0J28d", - "width": "fill_container", - "stroke": { - "thickness": { - "bottom": 1 - }, - "fill": "#FFFFFF1A" - }, - "padding": [ - 8, - 12 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "CQ0ns", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "YYAvV", - "width": 12, - "height": 12, - "iconFontName": "sparkles", - "iconFontFamily": "lucide", - "fill": "$accent" - }, - { - "type": "text", - "id": "N7Z0Z", - "fill": "#FBF5E6", - "content": "AI 建议", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "700" - }, - { - "type": "text", - "id": "x7mouF", - "fill": "#9CA3AF", - "content": "· 添加反向代理", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "icon_font", - "id": "ZxlpL", - "width": 14, - "height": 14, - "iconFontName": "x", - "iconFontFamily": "lucide", - "fill": "#9CA3AF" - } - ] - }, - { - "type": "frame", - "id": "BxlIj", - "width": "fill_container", - "height": 18, - "fill": "#16653433", - "padding": [ - 0, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "wC644", - "fill": "#86EFAC", - "content": "+ location /api {", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "WqBhF", - "width": "fill_container", - "height": 18, - "fill": "#16653433", - "padding": [ - 0, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "JPqI7", - "fill": "#86EFAC", - "content": "+ proxy_pass http://localhost:8082;", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "cmRJk", - "width": "fill_container", - "height": 18, - "fill": "#16653433", - "padding": [ - 0, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "rfiI7", - "fill": "#86EFAC", - "content": "+ proxy_http_version 1.1;", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "VgVP0", - "width": "fill_container", - "height": 18, - "fill": "#16653433", - "padding": [ - 0, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "oNk5n", - "fill": "#86EFAC", - "content": "+ }", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "RLegb", - "width": "fill_container", - "stroke": { - "thickness": { - "top": 1 - }, - "fill": "#FFFFFF1A" - }, - "gap": 6, - "padding": [ - 8, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "k5Mfx", - "width": "fill_container", - "height": 28, - "fill": "$accent", - "cornerRadius": 8, - "gap": 4, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "EuvnO", - "width": 12, - "height": 12, - "iconFontName": "check", - "iconFontFamily": "lucide", - "fill": "$primary" - }, - { - "type": "text", - "id": "ujOHz", - "fill": "$primary", - "content": "应用到第 11 行", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "nMrgG", - "height": 28, - "fill": "#FFFFFF14", - "cornerRadius": 8, - "stroke": { - "thickness": 1, - "fill": "#FFFFFF2A" - }, - "padding": [ - 0, - 10 - ], - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "oA9PZ", - "fill": "#E5E7EB", - "content": "忽略", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "600" - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "cRoyG", - "width": "fill_container", - "height": "fill_container", - "fill": "$surface", - "stroke": { - "thickness": { - "top": 1 - }, - "fill": "$border" - }, - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "Da3tm", - "width": "fill_container", - "height": 16, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 2, - "id": "ztbam", - "fill": "$border-strong", - "width": 36, - "height": 4 - } - ] - }, - { - "type": "frame", - "id": "WvldY", - "width": "fill_container", - "padding": [ - 0, - 16, - 8, - 16 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "mlIz5", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "oeTYH", - "width": 24, - "height": 24, - "fill": "$accent", - "cornerRadius": 8, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "OzaDh", - "width": 12, - "height": 12, - "iconFontName": "sparkles", - "iconFontFamily": "lucide", - "fill": "#FFFFFF" - } - ] - }, - { - "type": "frame", - "id": "ITbLc", - "layout": "vertical", - "children": [ - { - "type": "text", - "id": "Y4BhL1", - "fill": "$font-primary", - "content": "AI 助手", - "fontFamily": "Inter", - "fontSize": 13, - "fontWeight": "700" - }, - { - "type": "frame", - "id": "GgqGC", - "gap": 4, - "alignItems": "center", - "children": [ - { - "type": "ellipse", - "id": "LfZTb", - "fill": "$success", - "width": 5, - "height": 5 - }, - { - "type": "text", - "id": "gGXp2", - "fill": "$font-muted", - "content": "已连接 nginx 上下文", - "fontFamily": "Inter", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "j5X5j", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "XtQ7k", - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 4, - "padding": [ - 3, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "SPMa8", - "fill": "$font-secondary", - "content": "GPT-4o", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "600" - }, - { - "type": "icon_font", - "id": "iNMFm", - "width": 10, - "height": 10, - "iconFontName": "chevron-down", - "iconFontFamily": "lucide", - "fill": "$font-muted" - } - ] - }, - { - "type": "icon_font", - "id": "P0tYMC", - "width": 16, - "height": 16, - "iconFontName": "chevron-down", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - } - ] - } - ] - }, - { - "type": "frame", - "id": "BbGbI", - "width": "fill_container", - "height": "fill_container", - "layout": "vertical", - "gap": 12, - "padding": [ - 4, - 16, - 8, - 16 - ], - "children": [ - { - "type": "frame", - "id": "sDxne", - "width": "fill_container", - "justifyContent": "end", - "children": [ - { - "type": "frame", - "id": "HPEPt", - "width": 280, - "fill": "$accent-soft", - "cornerRadius": 14, - "padding": [ - 8, - 12 - ], - "children": [ - { - "type": "text", - "id": "G2c0u", - "fill": "$primary", - "textGrowth": "fixed-width", - "width": "fill_container", - "content": "首页访问 502,可能怎么修?要把请求转给 8082 端口。", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "500" - } - ] - } - ] - }, - { - "type": "frame", - "id": "FSOeJ", - "width": "fill_container", - "gap": 8, - "children": [ - { - "type": "frame", - "id": "Mg6TH", - "width": 24, - "height": 24, - "fill": "$accent", - "cornerRadius": 8, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "MTSUS", - "width": 12, - "height": 12, - "iconFontName": "sparkles", - "iconFontFamily": "lucide", - "fill": "#FFFFFF" - } - ] - }, - { - "type": "frame", - "id": "oZN0i", - "width": "fill_container", - "layout": "vertical", - "gap": 6, - "children": [ - { - "type": "frame", - "id": "oy69m", - "width": "fill_container", - "fill": "$surface-card", - "cornerRadius": 14, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "layout": "vertical", - "gap": 6, - "padding": [ - 10, - 12 - ], - "children": [ - { - "type": "text", - "id": "Z3U6z", - "fill": "$font-primary", - "textGrowth": "fixed-width", - "width": "fill_container", - "content": "你目前的 `location /` 只指向静态目录,要把 / 转发到 8082,需要新增反向代理:", - "lineHeight": 1.4, - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "500" - }, - { - "type": "frame", - "id": "vTj7S", - "width": "fill_container", - "fill": "$surface-inverse", - "cornerRadius": 8, - "layout": "vertical", - "gap": 1, - "padding": [ - 8, - 10 - ], - "children": [ - { - "type": "frame", - "id": "HxGEK", - "children": [ - { - "type": "text", - "id": "d0MP4", - "fill": "#569CD6", - "content": "location ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "GTJ3O", - "fill": "#CE9178", - "content": "/api", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "o5mYvl", - "fill": "#D4D4D4", - "content": " {", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "gXRYv", - "children": [ - { - "type": "text", - "id": "kmsLG", - "fill": "#569CD6", - "content": " proxy_pass", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "UaGXN", - "fill": "#CE9178", - "content": " http://localhost:8082", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "OMg9h", - "fill": "#D4D4D4", - "content": ";", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "w5eHEZ", - "children": [ - { - "type": "text", - "id": "nB3Er", - "fill": "#D4D4D4", - "content": "}", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "U4oqM", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "LXYAZ", - "fill": "$primary", - "cornerRadius": 8, - "gap": 4, - "padding": [ - 5, - 10 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "nYG4H", - "width": 11, - "height": 11, - "iconFontName": "wand-sparkles", - "iconFontFamily": "lucide", - "fill": "$font-on-primary" - }, - { - "type": "text", - "id": "F131kO", - "fill": "$font-on-primary", - "content": "应用到代码", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "e7fzaA", - "fill": "$surface-card", - "cornerRadius": 8, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 4, - "padding": [ - 5, - 10 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "cUToh", - "width": 11, - "height": 11, - "iconFontName": "copy", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - }, - { - "type": "text", - "id": "N2KMHo", - "fill": "$font-secondary", - "content": "复制", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "kSQKU", - "fill": "$surface-card", - "cornerRadius": 8, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 4, - "padding": [ - 5, - 10 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "S77IWP", - "width": 11, - "height": 11, - "iconFontName": "list-tree", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - }, - { - "type": "text", - "id": "J8Q72t", - "fill": "$font-secondary", - "content": "解释", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "600" - } - ] - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "TAG5U", - "width": "fill_container", - "fill": "$surface", - "stroke": { - "thickness": { - "top": 1 - }, - "fill": "$border" - }, - "layout": "vertical", - "gap": 8, - "padding": [ - 8, - 16, - 16, - 16 - ], - "children": [ - { - "type": "frame", - "id": "XHAQP", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "cgMwJ", - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 4, - "padding": [ - 4, - 9 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "a3iWlL", - "width": 10, - "height": 10, - "iconFontName": "book-open", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - }, - { - "type": "text", - "id": "wOPys", - "fill": "$font-secondary", - "content": "解释代码", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "OUXGK", - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 4, - "padding": [ - 4, - 9 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "SlDN7", - "width": 10, - "height": 10, - "iconFontName": "wand", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - }, - { - "type": "text", - "id": "fizBV", - "fill": "$font-secondary", - "content": "优化", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "BtLGG", - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 4, - "padding": [ - 4, - 9 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "EZcw8", - "width": 10, - "height": 10, - "iconFontName": "bug", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - }, - { - "type": "text", - "id": "hmywW", - "fill": "$font-secondary", - "content": "找 bug", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "k7He2Q", - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 4, - "padding": [ - 4, - 9 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "dnyTo", - "width": 10, - "height": 10, - "iconFontName": "test-tube", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - }, - { - "type": "text", - "id": "cOSTp", - "fill": "$font-secondary", - "content": "写测试", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "600" - } - ] - } - ] - }, - { - "type": "frame", - "id": "dhWIt", - "width": "fill_container", - "height": 44, - "fill": "$surface-card", - "cornerRadius": 22, - "stroke": { - "thickness": 1, - "fill": "$border-strong" - }, - "gap": 8, - "padding": [ - 0, - 6, - 0, - 14 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "oUfDb", - "width": 14, - "height": 14, - "iconFontName": "at-sign", - "iconFontFamily": "lucide", - "fill": "$font-muted" - }, - { - "type": "text", - "id": "pYGKB", - "fill": "$font-muted", - "textGrowth": "fixed-width", - "width": "fill_container", - "content": "向 AI 提问,或输入 @ 引用文件...", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "frame", - "id": "KgeiP", - "width": 32, - "height": 32, - "fill": "$primary", - "cornerRadius": 999, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "OpcYP", - "width": 14, - "height": 14, - "iconFontName": "arrow-up", - "iconFontFamily": "lucide", - "fill": "$font-on-primary" - } - ] - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "DdRKa", - "x": 6866, - "y": 904, - "name": "代码编辑页(差异视图)", - "clip": true, - "width": 390, - "height": 1087, - "fill": "$surface", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "y1LSOm", - "name": "状态栏", - "width": "fill_container", - "height": 62, - "padding": [ - 0, - 20 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "GYwaM", - "fill": "$font-primary", - "content": "9:41", - "fontFamily": "Inter", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "frame", - "id": "JpwgP", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "WRH34", - "width": 16, - "height": 16, - "iconFontName": "signal", - "iconFontFamily": "lucide", - "fill": "$font-primary" - }, - { - "type": "icon_font", - "id": "k1KTC", - "width": 16, - "height": 16, - "iconFontName": "wifi", - "iconFontFamily": "lucide", - "fill": "$font-primary" - }, - { - "type": "icon_font", - "id": "HJAoN", - "width": 22, - "height": 16, - "iconFontName": "battery-full", - "iconFontFamily": "lucide", - "fill": "$font-primary" - } - ] - } - ] - }, - { - "type": "frame", - "id": "OXHhy", - "name": "顶部应用栏", - "width": "fill_container", - "height": 56, - "gap": 12, - "padding": [ - 0, - 16 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "basgv", - "gap": 10, - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "T5ONVm", - "width": 22, - "height": 22, - "iconFontName": "chevron-left", - "iconFontFamily": "lucide", - "fill": "$font-primary" - }, - { - "type": "frame", - "id": "D46Z9", - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "text", - "id": "wf603", - "fill": "$font-primary", - "content": "nginx.conf", - "fontFamily": "Inter", - "fontSize": 16, - "fontWeight": "600" - }, - { - "type": "text", - "id": "pGUED", - "fill": "$font-muted", - "content": "/etc/nginx", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "C4RVx", - "gap": 14, - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "j8dTn", - "width": 22, - "height": 22, - "iconFontName": "undo-2", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - }, - { - "type": "frame", - "id": "EOlGR", - "width": 28, - "height": 28, - "fill": "$accent-soft", - "cornerRadius": 8, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "RZ7MJ", - "width": 18, - "height": 18, - "iconFontName": "check", - "iconFontFamily": "lucide", - "fill": "$success" - } - ] - }, - { - "type": "icon_font", - "id": "vBiUy", - "width": 22, - "height": 22, - "iconFontName": "ellipsis", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - } - ] - } - ] - }, - { - "type": "frame", - "id": "JKQn4", - "name": "视图切换", - "width": "fill_container", - "height": 38, - "padding": [ - 0, - 16 - ], - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "K2ZTc", - "width": "fill_container", - "height": 32, - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "padding": 3, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "kL7rC", - "width": "fill_container", - "height": "fill_container", - "fill": "#00000000", - "cornerRadius": "$radius-chip", - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "URiaX", - "fill": "$font-secondary", - "content": "原文", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "500" - } - ] - }, - { - "type": "frame", - "id": "rHGPt", - "width": "fill_container", - "height": "fill_container", - "fill": "$primary", - "cornerRadius": "$radius-chip", - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "qdhnx", - "fill": "$font-on-primary", - "content": "差异", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "G3LsD", - "width": "fill_container", - "height": "fill_container", - "fill": "#00000000", - "cornerRadius": "$radius-chip", - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "XLSW1", - "fill": "$font-secondary", - "content": "预览", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "500" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "NEx7c", - "name": "对比上下文", - "width": "fill_container", - "height": 46, - "gap": 8, - "padding": [ - 10, - 16, - 4, - 16 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "t7BEf", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "fGvWx", - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 6, - "padding": [ - 5, - 9 - ], - "alignItems": "center", - "children": [ - { - "type": "ellipse", - "id": "tNF0X", - "fill": "$danger", - "width": 6, - "height": 6 - }, - { - "type": "text", - "id": "pqbuo", - "fill": "$font-primary", - "content": "本地修改", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "BD5Fb", - "fill": "$font-muted", - "content": "2分钟前", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "icon_font", - "id": "cq3Hj", - "width": 14, - "height": 14, - "iconFontName": "arrow-right", - "iconFontFamily": "lucide", - "fill": "$font-muted" - }, - { - "type": "frame", - "id": "IYdaY", - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 6, - "padding": [ - 5, - 9 - ], - "alignItems": "center", - "children": [ - { - "type": "ellipse", - "id": "HYuf8", - "fill": "$success", - "width": 6, - "height": 6 - }, - { - "type": "text", - "id": "L3Qu6", - "fill": "$font-primary", - "content": "远程版本", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "GWKrP", - "fill": "$font-muted", - "content": "v2.1.4", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "ZRc3Y", - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 6, - "padding": [ - 5, - 9 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "h3M1Q", - "fill": "$success", - "content": "+12", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "wG3JZ", - "fill": "$danger", - "content": "-8", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - } - ] - }, - { - "type": "frame", - "id": "EBRAN", - "name": "差异代码区", - "clip": true, - "width": "fill_container", - "height": "fill_container", - "fill": "$surface-inverse", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "rPD4C", - "width": "fill_container", - "height": 22, - "fill": "#3B82F622", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "JfGZZ", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "YAeQn", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "z2XkBx", - "fill": "#60A5FA", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "T9Mzkn", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "FHfBc", - "fill": "#60A5FA", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "X6J0lv", - "fill": "#00000000", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "YkGmh", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "h8iBD", - "fill": "#93C5FD", - "textGrowth": "fixed-width", - "width": 10, - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "o48TS", - "fill": "#93C5FD", - "content": "@@ -38,9 +38,12 @@ server {", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "n4NWb", - "width": "fill_container", - "height": 22, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "AHYRf", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "r7wgIK", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "g72up1", - "fill": "#6B7280", - "content": "38", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "HvLPO", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "q8dMKh", - "fill": "#6B7280", - "content": "38", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "i0UOV", - "fill": "#00000000", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "X88Q2", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "fAoHd", - "fill": "#D4D4D4", - "textGrowth": "fixed-width", - "width": 10, - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "vd1ZV", - "fill": "#D4D4D4", - "content": " listen 80;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "dklvJ", - "width": "fill_container", - "height": 22, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "AQydO", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "t1Ajfd", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "moCVP", - "fill": "#6B7280", - "content": "39", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "S7xJ3T", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "PwUIS", - "fill": "#6B7280", - "content": "39", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "N7nnO", - "fill": "#00000000", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "FtAhA", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "Dze54", - "fill": "#D4D4D4", - "textGrowth": "fixed-width", - "width": 10, - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "pYbZB", - "fill": "#D4D4D4", - "content": " server_name easynode.local;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "HuaRn", - "width": "fill_container", - "height": 22, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "D7diH", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "l2OoG", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "A4amR", - "fill": "#6B7280", - "content": "40", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "b9DQuN", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "IP064", - "fill": "#6B7280", - "content": "40", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "xnB6l", - "fill": "#00000000", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "oDfz2", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "Eh92I", - "fill": "#D4D4D4", - "textGrowth": "fixed-width", - "width": 10, - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "I5OuDg", - "fill": "#D4D4D4", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "TDka8", - "width": "fill_container", - "height": 22, - "fill": "#C0392B3D", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "s0Ddv5", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "UXwCG", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "l0CC4N", - "fill": "#FCA5A5", - "content": "41", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "syMI6", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "zIiD8", - "fill": "#FCA5A5", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "Pdqnm", - "fill": "$danger", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "ks394", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "Dgahn", - "fill": "#FCA5A5", - "textGrowth": "fixed-width", - "width": 10, - "content": "-", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "aonvZ", - "fill": "#FCA5A5", - "content": " root /var/www/html;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "GOQQQ", - "width": "fill_container", - "height": 22, - "fill": "#5A8E3A2E", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "u0BNs", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "EG37n", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "hAS2O", - "fill": "#86EFAC", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "S26Loo", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "UbWpK", - "fill": "#86EFAC", - "content": "41", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "AyQub", - "fill": "$success", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "zHm9L", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "XRZZf", - "fill": "#BBF7D0", - "textGrowth": "fixed-width", - "width": 10, - "content": "+", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "F7OWW", - "fill": "#BBF7D0", - "content": " root /var/www/easynode;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "KoCJF", - "width": "fill_container", - "height": 22, - "fill": "#5A8E3A2E", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "US8zg", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "mXIya", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "V4ovk", - "fill": "#86EFAC", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "H9pBqq", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "C1YhR", - "fill": "#86EFAC", - "content": "42", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "C6UYVN", - "fill": "$success", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "Lox8M", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "BHaTO", - "fill": "#BBF7D0", - "textGrowth": "fixed-width", - "width": 10, - "content": "+", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "T8elA", - "fill": "#BBF7D0", - "content": " index index.html index.htm;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "C6LIc", - "width": "fill_container", - "height": 22, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "VbQjk", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "mOhET", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "vEvxL", - "fill": "#6B7280", - "content": "42", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "mmgWp", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "C0B11", - "fill": "#6B7280", - "content": "43", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "ir42c", - "fill": "#00000000", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "T6lQkn", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "tPy52", - "fill": "#D4D4D4", - "textGrowth": "fixed-width", - "width": 10, - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "wvQFI", - "fill": "#D4D4D4", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "j2WY0Z", - "width": "fill_container", - "height": 22, - "fill": "#C0392B3D", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "OJfLP", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "uEVRs", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "ACCPP", - "fill": "#FCA5A5", - "content": "43", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "kVXLK", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "i1BYAC", - "fill": "#FCA5A5", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "V2ruLt", - "fill": "$danger", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "VNPt5", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "OvjQG", - "fill": "#FCA5A5", - "textGrowth": "fixed-width", - "width": 10, - "content": "-", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "YYeZt", - "fill": "#FCA5A5", - "content": " location / {", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "a5vVg", - "width": "fill_container", - "height": 22, - "fill": "#C0392B3D", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "d4lk6", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "v9wlM", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "mNyWB", - "fill": "#FCA5A5", - "content": "44", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "V6ud7Q", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "CpPSM", - "fill": "#FCA5A5", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "yNqNN", - "fill": "$danger", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "H8pPV0", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "oujRv", - "fill": "#FCA5A5", - "textGrowth": "fixed-width", - "width": 10, - "content": "-", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "h6Mnb", - "fill": "#FCA5A5", - "content": " try_files $uri =404;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "H75AZP", - "width": "fill_container", - "height": 22, - "fill": "#C0392B3D", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "k1VJh", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "XHOCG", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "vXQSZ", - "fill": "#FCA5A5", - "content": "45", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "lih6K", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "r5OVG", - "fill": "#FCA5A5", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "F3wrB", - "fill": "$danger", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "ItllW", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "TVy7M", - "fill": "#FCA5A5", - "textGrowth": "fixed-width", - "width": 10, - "content": "-", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "nEOrq", - "fill": "#FCA5A5", - "content": " }", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "xws3i", - "width": "fill_container", - "height": 22, - "fill": "#5A8E3A2E", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "GIJKH", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "nWg5a", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "a1PGm", - "fill": "#86EFAC", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "OMfPA", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "mb9GM", - "fill": "#86EFAC", - "content": "44", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "znkHY", - "fill": "$success", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "s5cEoA", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "ntcJk", - "fill": "#BBF7D0", - "textGrowth": "fixed-width", - "width": 10, - "content": "+", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "j8ioru", - "fill": "#BBF7D0", - "content": " location / {", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "Xu8eW", - "width": "fill_container", - "height": 22, - "fill": "#5A8E3A2E", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "ZE2kU", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "pVvDU", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "okOzd", - "fill": "#86EFAC", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "urj9z", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "HUZzt", - "fill": "#86EFAC", - "content": "45", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "H802gm", - "fill": "$success", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "JXLYR", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "sCtwr", - "fill": "#BBF7D0", - "textGrowth": "fixed-width", - "width": 10, - "content": "+", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "NzkM0", - "fill": "#BBF7D0", - "content": " proxy_pass http://localhost:8082;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "jhyNI", - "width": "fill_container", - "height": 22, - "fill": "#5A8E3A2E", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "z9164", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "LxVpp", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "OChlV", - "fill": "#86EFAC", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "SPG16", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "YGXu3", - "fill": "#86EFAC", - "content": "46", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "yWomy", - "fill": "$success", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "E73FvC", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "GKERP", - "fill": "#BBF7D0", - "textGrowth": "fixed-width", - "width": 10, - "content": "+", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "nSxba", - "fill": "#BBF7D0", - "content": " proxy_http_version 1.1;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "O310MZ", - "width": "fill_container", - "height": 22, - "fill": "#5A8E3A2E", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "O9z8Oo", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "G4fJ3b", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "ykP1S", - "fill": "#86EFAC", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "xTa3D", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "K85Tf", - "fill": "#86EFAC", - "content": "47", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "vkhIG", - "fill": "$success", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "i4z8z", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "eWeuq", - "fill": "#BBF7D0", - "textGrowth": "fixed-width", - "width": 10, - "content": "+", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "Fo5v5", - "fill": "#BBF7D0", - "content": " proxy_set_header Host $host;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "MkZRh", - "width": "fill_container", - "height": 22, - "fill": "#5A8E3A2E", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "Fo3VT", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "uQRbX", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "CObIG", - "fill": "#86EFAC", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "oymXB", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "AZzOY", - "fill": "#86EFAC", - "content": "48", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "v33Rzd", - "fill": "$success", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "Klfp3", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "dfYWP", - "fill": "#BBF7D0", - "textGrowth": "fixed-width", - "width": 10, - "content": "+", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "gxK83", - "fill": "#BBF7D0", - "content": " }", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "ApkAy", - "width": "fill_container", - "height": 22, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "uQzYu", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "XTkuY", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "ODm7T", - "fill": "#6B7280", - "content": "46", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "xxyXh", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "PMkff", - "fill": "#6B7280", - "content": "49", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "Uh3LQ", - "fill": "#00000000", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "oi9sE", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "a24hN9", - "fill": "#D4D4D4", - "textGrowth": "fixed-width", - "width": 10, - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "GrO7K", - "fill": "#D4D4D4", - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "Ulqv3", - "width": "fill_container", - "height": 22, - "fill": "#00000000", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "X6HWk", - "width": 56, - "height": "fill_container", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "ty0fX", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "A2eR8s", - "fill": "#6B7280", - "content": "47", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "V9yBzh", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 6, - 0, - 2 - ], - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "z80BGF", - "fill": "#6B7280", - "content": "50", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - }, - { - "type": "rectangle", - "id": "Vt46q", - "fill": "#00000000", - "width": 2, - "height": "fill_container" - } - ] - }, - { - "type": "frame", - "id": "DqQuS", - "width": "fill_container", - "height": "fill_container", - "padding": [ - 0, - 8 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "TQ6x4", - "fill": "#D4D4D4", - "textGrowth": "fixed-width", - "width": 10, - "content": " ", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - }, - { - "type": "text", - "id": "bfMSd", - "fill": "#D4D4D4", - "content": " gzip on;", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "TVcFt", - "name": "底部操作栏", - "width": "fill_container", - "fill": "$surface", - "stroke": { - "thickness": { - "top": 1 - }, - "fill": "$border" - }, - "layout": "vertical", - "gap": 10, - "padding": [ - 12, - 16, - 16, - 16 - ], - "children": [ - { - "type": "frame", - "id": "S7Gjp", - "width": "fill_container", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "ellipse", - "id": "B9U5YZ", - "fill": "$accent", - "width": 6, - "height": 6 - }, - { - "type": "text", - "id": "s3NLI", - "fill": "$font-secondary", - "content": "6 个修改未保存 · nginx.conf", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "s1nmxg", - "width": "fill_container", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "I6piD", - "width": "fill_container", - "height": 42, - "fill": "$primary", - "cornerRadius": "$radius-control", - "gap": 8, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "b5Kil", - "width": 18, - "height": 18, - "iconFontName": "cloud-upload", - "iconFontFamily": "lucide", - "fill": "$font-on-primary" - }, - { - "type": "text", - "id": "OTfnR", - "fill": "$font-on-primary", - "content": "保存到远程", - "fontFamily": "Inter", - "fontSize": 14, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "nAsoY", - "width": 42, - "height": 42, - "fill": "$surface-card", - "cornerRadius": "$radius-control", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "aUJsk", - "width": 18, - "height": 18, - "iconFontName": "rotate-ccw", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - } - ] - }, - { - "type": "frame", - "id": "S6Lj6", - "width": 42, - "height": 42, - "fill": "$surface-card", - "cornerRadius": "$radius-control", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "MkPPK", - "width": 18, - "height": 18, - "iconFontName": "columns-2", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "zbuYi", - "x": 7296, - "y": 904, - "name": "文件页(网格视图)", - "clip": true, - "width": 390, - "height": 1087, - "fill": "$surface", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "cNv0K", - "width": "fill_container", - "height": 62, - "padding": [ - 0, - 20 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "z2iloF", - "fill": "$font-primary", - "content": "9:41", - "fontFamily": "Inter", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "frame", - "id": "jNe7c", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "gvYY3", - "width": 16, - "height": 16, - "iconFontName": "signal", - "iconFontFamily": "lucide", - "fill": "$font-primary" - }, - { - "type": "icon_font", - "id": "f8Un2h", - "width": 16, - "height": 16, - "iconFontName": "wifi", - "iconFontFamily": "lucide", - "fill": "$font-primary" - }, - { - "type": "icon_font", - "id": "FWbgY", - "width": 22, - "height": 16, - "iconFontName": "battery-full", - "iconFontFamily": "lucide", - "fill": "$font-primary" - } - ] - } - ] - }, - { - "type": "frame", - "id": "neMs8", - "width": "fill_container", - "height": 56, - "padding": [ - 0, - 16 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "UQd4o", - "gap": 10, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "JUDBV", - "width": 32, - "height": 32, - "fill": "$accent", - "cornerRadius": 8, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "vq49b", - "fill": "#FFFFFF", - "content": ">_", - "fontFamily": "JetBrains Mono", - "fontSize": 13, - "fontWeight": "700" - } - ] - }, - { - "type": "text", - "id": "fKbta", - "fill": "$font-primary", - "content": "文件", - "fontFamily": "Inter", - "fontSize": 20, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "DkoPt", - "height": 32, - "fill": "$surface-card", - "cornerRadius": "$radius-control", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "padding": 3, - "children": [ - { - "type": "frame", - "id": "HLruo", - "width": 38, - "height": 26, - "fill": "$primary", - "cornerRadius": 7, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "TzOEb", - "width": 14, - "height": 14, - "iconFontName": "layout-grid", - "iconFontFamily": "lucide", - "fill": "$font-on-primary" - } - ] - }, - { - "type": "frame", - "id": "WF81r", - "width": 38, - "height": 26, - "fill": "#00000000", - "cornerRadius": 7, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "Ehxe7", - "width": 14, - "height": 14, - "iconFontName": "list", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "udxP7", - "width": "fill_container", - "height": 36, - "padding": [ - 0, - 16 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "kJh52", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "e4rs5", - "width": 18, - "height": 18, - "iconFontName": "chevron-left", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - }, - { - "type": "frame", - "id": "mTgqd", - "fill": "$surface-card", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "gap": 4, - "padding": [ - 4, - 10 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "FO8UQ", - "fill": "$font-secondary", - "content": "/root/easynode/static", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "500" - } - ] - } - ] - }, - { - "type": "icon_font", - "id": "kfEVF", - "width": 16, - "height": 16, - "iconFontName": "refresh-cw", - "iconFontFamily": "lucide", - "fill": "$font-secondary" - } - ] - }, - { - "type": "frame", - "id": "kg2oK", - "width": "fill_container", - "gap": 6, - "padding": [ - 0, - 16, - 4, - 16 - ], - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "jrFXO", - "fill": "$primary", - "cornerRadius": "$radius-chip", - "padding": [ - 5, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "T2N2y", - "fill": "$font-on-primary", - "content": "全部 24", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "EUxvh", - "fill": "#00000000", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "padding": [ - 5, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "p4P6B", - "fill": "$font-secondary", - "content": "图片 8", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "ynDnz", - "fill": "#00000000", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "padding": [ - 5, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "O8X5U", - "fill": "$font-secondary", - "content": "影片 3", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "wagch", - "fill": "#00000000", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "padding": [ - 5, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "WK2h0", - "fill": "$font-secondary", - "content": "文档 6", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "suJVi", - "fill": "#00000000", - "cornerRadius": "$radius-chip", - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "padding": [ - 5, - 12 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "Vq3Wl", - "fill": "$font-secondary", - "content": "文件夹 7", - "fontFamily": "Inter", - "fontSize": 12, - "fontWeight": "600" - } - ] - } - ] - }, - { - "type": "frame", - "id": "o6OQd", - "width": "fill_container", - "layout": "vertical", - "gap": 10, - "padding": [ - 10, - 16, - 12, - 16 - ], - "children": [ - { - "type": "frame", - "id": "v31k1I", - "width": "fill_container", - "gap": 10, - "children": [ - { - "type": "frame", - "id": "Z3Cy7", - "width": "fill_container", - "height": 148, - "fill": "$surface-card", - "cornerRadius": 14, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#5C45200D", - "offset": { - "x": 0, - "y": 3 - }, - "blur": 12 - }, - "layout": "vertical", - "children": [ - { - "type": "rectangle", - "cornerRadius": [ - 4, - 4, - 0, - 0 - ], - "id": "M1k6RO", - "layoutPosition": "absolute", - "x": 14, - "y": -1, - "fill": "$accent", - "width": 56, - "height": 8 - }, - { - "type": "frame", - "id": "zcwvL", - "width": "fill_container", - "height": "fill_container", - "layout": "vertical", - "gap": 6, - "padding": [ - 12, - 14 - ], - "justifyContent": "center", - "children": [ - { - "type": "icon_font", - "id": "QCpN8", - "width": 36, - "height": 36, - "iconFontName": "folder", - "iconFontFamily": "lucide", - "fill": "$accent" - }, - { - "type": "frame", - "id": "MTPIo", - "width": "fill_container", - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "text", - "id": "fsSvS", - "fill": "$font-primary", - "textGrowth": "fixed-width", - "width": "fill_container", - "content": "easynode", - "fontFamily": "Inter", - "fontSize": 14, - "fontWeight": "700" - }, - { - "type": "frame", - "id": "i3XVgd", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "T0eIgm", - "fill": "$font-muted", - "content": "24 项", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "Lt8or", - "fill": "$font-muted", - "content": "·", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "rpxlA", - "fill": "$font-muted", - "content": "4.0 KB", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "YmzMl", - "width": "fill_container", - "height": 148, - "fill": "$surface-card", - "cornerRadius": 14, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#5C45200D", - "offset": { - "x": 0, - "y": 3 - }, - "blur": 12 - }, - "layout": "vertical", - "children": [ - { - "type": "rectangle", - "cornerRadius": [ - 4, - 4, - 0, - 0 - ], - "id": "yn1X2", - "layoutPosition": "absolute", - "x": 14, - "y": -1, - "fill": "$accent", - "width": 56, - "height": 8 - }, - { - "type": "frame", - "id": "o9xIbY", - "width": "fill_container", - "height": "fill_container", - "layout": "vertical", - "gap": 6, - "padding": [ - 12, - 14 - ], - "justifyContent": "center", - "children": [ - { - "type": "frame", - "id": "ZRAhX", - "gap": 4, - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "sbT8a", - "fill": { - "type": "image", - "enabled": true, - "url": "https://images.unsplash.com/photo-1551434678-e076c223a692?w=200", - "mode": "fill" - }, - "width": 28, - "height": 36, - "stroke": { - "thickness": 1, - "fill": "#FFFFFFAA" - } - }, - { - "type": "rectangle", - "cornerRadius": 4, - "id": "yToqE", - "fill": { - "type": "image", - "enabled": true, - "url": "https://images.unsplash.com/photo-1517694712202-14dd9538aa97?w=200", - "mode": "fill" - }, - "width": 28, - "height": 36, - "stroke": { - "thickness": 1, - "fill": "#FFFFFFAA" - } - }, - { - "type": "rectangle", - "cornerRadius": 4, - "id": "IhMnn", - "fill": { - "type": "image", - "enabled": true, - "url": "https://images.unsplash.com/photo-1498050108023-c5249f4df085?w=200", - "mode": "fill" - }, - "width": 28, - "height": 36, - "stroke": { - "thickness": 1, - "fill": "#FFFFFFAA" - } - } - ] - }, - { - "type": "frame", - "id": "ZYGEh", - "width": "fill_container", - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "text", - "id": "nkOnO", - "fill": "$font-primary", - "textGrowth": "fixed-width", - "width": "fill_container", - "content": "screenshots", - "fontFamily": "Inter", - "fontSize": 14, - "fontWeight": "700" - }, - { - "type": "frame", - "id": "jL4kg", - "gap": 6, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "ap3Gj", - "fill": "$font-muted", - "content": "8 张图片", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "eFev2", - "fill": "$font-muted", - "content": "·", - "fontFamily": "Inter", - "fontSize": 11, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "jHeZr", - "fill": "$font-muted", - "content": "12.4 MB", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "A30HN", - "width": "fill_container", - "gap": 10, - "children": [ - { - "type": "frame", - "id": "P9TrjT", - "width": "fill_container", - "height": 148, - "fill": { - "type": "image", - "enabled": true, - "url": "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400", - "mode": "fill" - }, - "cornerRadius": 14, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#5C452014", - "offset": { - "x": 0, - "y": 3 - }, - "blur": 12 - }, - "layout": "vertical", - "children": [ - { - "type": "rectangle", - "cornerRadius": [ - 0, - 0, - 14, - 14 - ], - "id": "Vy4YX", - "layoutPosition": "absolute", - "x": 0, - "y": 100, - "fill": { - "type": "gradient", - "gradientType": "linear", - "enabled": true, - "rotation": 180, - "size": { - "height": 1 - }, - "colors": [ - { - "color": "#0A0F1400", - "position": 0 - }, - { - "color": "#0A0F14CC", - "position": 1 - } - ] - }, - "width": 200, - "height": 68 - }, - { - "type": "frame", - "id": "kGPXI", - "layoutPosition": "absolute", - "x": 10, - "y": 10, - "fill": "#0A0F14B3", - "cornerRadius": 6, - "gap": 4, - "padding": [ - 3, - 7 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "hoL0H", - "width": 10, - "height": 10, - "iconFontName": "image", - "iconFontFamily": "lucide", - "fill": "#FFFFFF" - }, - { - "type": "text", - "id": "hVo8h", - "fill": "#FFFFFF", - "content": "1920×1080", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "NSf7q", - "layoutPosition": "absolute", - "x": 0, - "y": 116, - "width": 174, - "height": 50, - "layout": "vertical", - "gap": 2, - "padding": [ - 0, - 12 - ], - "justifyContent": "center", - "children": [ - { - "type": "text", - "id": "uak77", - "fill": "#FFFFFF", - "textGrowth": "fixed-width", - "width": 150, - "content": "sunset.jpg", - "fontFamily": "Inter", - "fontSize": 13, - "fontWeight": "700" - }, - { - "type": "text", - "id": "r0GkGV", - "fill": "#E5E7EB", - "content": "1.2 MB", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "w6yuo", - "width": "fill_container", - "height": 148, - "fill": { - "type": "image", - "enabled": true, - "url": "https://images.unsplash.com/photo-1500964757637-c85e8a162699?w=400", - "mode": "fill" - }, - "cornerRadius": 14, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#5C452014", - "offset": { - "x": 0, - "y": 3 - }, - "blur": 12 - }, - "layout": "vertical", - "children": [ - { - "type": "rectangle", - "cornerRadius": [ - 0, - 0, - 14, - 14 - ], - "id": "zDUAz", - "layoutPosition": "absolute", - "x": 0, - "y": 100, - "fill": { - "type": "gradient", - "gradientType": "linear", - "enabled": true, - "rotation": 180, - "size": { - "height": 1 - }, - "colors": [ - { - "color": "#0A0F1400", - "position": 0 - }, - { - "color": "#0A0F14CC", - "position": 1 - } - ] - }, - "width": 200, - "height": 68 - }, - { - "type": "frame", - "id": "VyRwd", - "layoutPosition": "absolute", - "x": 10, - "y": 10, - "fill": "#0A0F14B3", - "cornerRadius": 6, - "gap": 4, - "padding": [ - 3, - 7 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "XRE6C", - "width": 10, - "height": 10, - "iconFontName": "image", - "iconFontFamily": "lucide", - "fill": "#FFFFFF" - }, - { - "type": "text", - "id": "lkkAI", - "fill": "#FFFFFF", - "content": "2400×1600", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "cbc20", - "layoutPosition": "absolute", - "x": 0, - "y": 116, - "width": 174, - "height": 50, - "layout": "vertical", - "gap": 2, - "padding": [ - 0, - 12 - ], - "justifyContent": "center", - "children": [ - { - "type": "text", - "id": "vZSpX", - "fill": "#FFFFFF", - "textGrowth": "fixed-width", - "width": 150, - "content": "lake.jpg", - "fontFamily": "Inter", - "fontSize": 13, - "fontWeight": "700" - }, - { - "type": "text", - "id": "F4OW3P", - "fill": "#E5E7EB", - "content": "987 KB", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "I6Kr0Q", - "width": "fill_container", - "gap": 10, - "children": [ - { - "type": "frame", - "id": "KQhQt", - "width": "fill_container", - "height": 148, - "fill": { - "type": "image", - "enabled": true, - "url": "https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=400", - "mode": "fill" - }, - "cornerRadius": 14, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#5C452014", - "offset": { - "x": 0, - "y": 3 - }, - "blur": 12 - }, - "children": [ - { - "type": "rectangle", - "cornerRadius": 14, - "id": "FFZTf", - "layoutPosition": "absolute", - "x": 0, - "y": 0, - "fill": { - "type": "gradient", - "gradientType": "linear", - "enabled": true, - "rotation": 180, - "size": { - "height": 1 - }, - "colors": [ - { - "color": "#0A0F1422", - "position": 0 - }, - { - "color": "#0A0F14CC", - "position": 1 - } - ] - }, - "width": 200, - "height": 168 - }, - { - "type": "frame", - "id": "dDPRn", - "layoutPosition": "absolute", - "x": 65, - "y": 50, - "width": 48, - "height": 48, - "fill": "#FFFFFFE6", - "cornerRadius": 999, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#00000055", - "offset": { - "x": 0, - "y": 4 - }, - "blur": 18 - }, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "wDISl", - "width": 20, - "height": 20, - "iconFontName": "play", - "iconFontFamily": "lucide", - "fill": "$primary" - } - ] - }, - { - "type": "frame", - "id": "Tjq6d", - "layoutPosition": "absolute", - "x": 130, - "y": 10, - "fill": "#0A0F14B3", - "cornerRadius": 6, - "gap": 4, - "padding": [ - 3, - 7 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "cmZVw", - "width": 10, - "height": 10, - "iconFontName": "film", - "iconFontFamily": "lucide", - "fill": "#FFFFFF" - }, - { - "type": "text", - "id": "T10iK", - "fill": "#FFFFFF", - "content": "15:42", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "Hxpl6", - "layoutPosition": "absolute", - "x": 0, - "y": 116, - "width": 174, - "height": 50, - "layout": "vertical", - "gap": 2, - "padding": [ - 0, - 12 - ], - "justifyContent": "center", - "children": [ - { - "type": "text", - "id": "dWgn4", - "fill": "#FFFFFF", - "textGrowth": "fixed-width", - "width": 150, - "content": "sunset-timelapse.mp4", - "fontFamily": "Inter", - "fontSize": 13, - "fontWeight": "700" - }, - { - "type": "text", - "id": "g9NXfb", - "fill": "#E5E7EB", - "content": "124 MB · MP4", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "iN6hE", - "width": "fill_container", - "height": 148, - "fill": { - "type": "image", - "enabled": true, - "url": "https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=400", - "mode": "fill" - }, - "cornerRadius": 14, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#5C452014", - "offset": { - "x": 0, - "y": 3 - }, - "blur": 12 - }, - "layout": "vertical", - "children": [ - { - "type": "rectangle", - "cornerRadius": [ - 0, - 0, - 14, - 14 - ], - "id": "sGKbc", - "layoutPosition": "absolute", - "x": 0, - "y": 100, - "fill": { - "type": "gradient", - "gradientType": "linear", - "enabled": true, - "rotation": 180, - "size": { - "height": 1 - }, - "colors": [ - { - "color": "#0A0F1400", - "position": 0 - }, - { - "color": "#0A0F14CC", - "position": 1 - } - ] - }, - "width": 200, - "height": 68 - }, - { - "type": "frame", - "id": "EBIwN", - "layoutPosition": "absolute", - "x": 10, - "y": 10, - "fill": "#0A0F14B3", - "cornerRadius": 6, - "gap": 4, - "padding": [ - 3, - 7 - ], - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "ZT6OI", - "width": 10, - "height": 10, - "iconFontName": "image", - "iconFontFamily": "lucide", - "fill": "#FFFFFF" - }, - { - "type": "text", - "id": "vvJtS", - "fill": "#FFFFFF", - "content": "1200×800", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "oDaWD", - "layoutPosition": "absolute", - "x": 0, - "y": 116, - "width": 174, - "height": 50, - "layout": "vertical", - "gap": 2, - "padding": [ - 0, - 12 - ], - "justifyContent": "center", - "children": [ - { - "type": "text", - "id": "qFhix", - "fill": "#FFFFFF", - "textGrowth": "fixed-width", - "width": 150, - "content": "chart.png", - "fontFamily": "Inter", - "fontSize": 13, - "fontWeight": "700" - }, - { - "type": "text", - "id": "AWYxj", - "fill": "#E5E7EB", - "content": "246 KB", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "K2Brw", - "width": "fill_container", - "gap": 10, - "children": [ - { - "type": "frame", - "id": "y58yfa", - "width": "fill_container", - "height": 148, - "fill": "$surface-inverse", - "cornerRadius": 14, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#5C452014", - "offset": { - "x": 0, - "y": 3 - }, - "blur": 12 - }, - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "vnGyB", - "layoutPosition": "absolute", - "x": 10, - "y": 10, - "fill": "#7E57C2", - "cornerRadius": 6, - "padding": [ - 3, - 7 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "OKjBH", - "fill": "#FFFFFF", - "content": "YAML", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "D3r5Gs", - "layoutPosition": "absolute", - "x": 10, - "y": 36, - "clip": true, - "width": 154, - "height": 78, - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "frame", - "id": "lCSt8", - "height": 13, - "children": [ - { - "type": "text", - "id": "hBclR", - "fill": "#569CD6", - "content": "version", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "YE4Nn", - "fill": "#D4D4D4", - "content": ": ", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "wzhG0", - "fill": "#CE9178", - "content": "\"3.8\"", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "b5PJWA", - "width": "fill_container", - "height": 13 - }, - { - "type": "frame", - "id": "nRKYP", - "height": 13, - "children": [ - { - "type": "text", - "id": "Qd4Qg", - "fill": "#569CD6", - "content": "services", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "v3UVH4", - "fill": "#D4D4D4", - "content": ":", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "d83Sfr", - "height": 13, - "children": [ - { - "type": "text", - "id": "mwT54", - "fill": "#9CDCFE", - "content": " easynode", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "jEduk", - "fill": "#D4D4D4", - "content": ":", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "F1uSMW", - "height": 13, - "children": [ - { - "type": "text", - "id": "AXKMX", - "fill": "#569CD6", - "content": " image", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "HzFn5", - "fill": "#CE9178", - "content": ": chaoszhu/easynode", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "ct5fb", - "height": 13, - "children": [ - { - "type": "text", - "id": "lGcd1", - "fill": "#569CD6", - "content": " ports", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "vgD6b", - "fill": "#D4D4D4", - "content": ":", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "rectangle", - "cornerRadius": [ - 0, - 0, - 14, - 14 - ], - "id": "Y9XSTk", - "layoutPosition": "absolute", - "x": 0, - "y": 116, - "fill": { - "type": "gradient", - "gradientType": "linear", - "enabled": true, - "rotation": 180, - "size": { - "height": 1 - }, - "colors": [ - { - "color": "#0A0F1400", - "position": 0 - }, - { - "color": "#0A0F14EE", - "position": 0.6 - } - ] - }, - "width": 200, - "height": 52 - }, - { - "type": "frame", - "id": "l8WXm", - "layoutPosition": "absolute", - "x": 0, - "y": 124, - "width": 174, - "height": 40, - "layout": "vertical", - "gap": 2, - "padding": [ - 0, - 12 - ], - "justifyContent": "center", - "children": [ - { - "type": "text", - "id": "xZYke", - "fill": "#FFFFFF", - "textGrowth": "fixed-width", - "width": 150, - "content": "docker-compose.yml", - "fontFamily": "Inter", - "fontSize": 13, - "fontWeight": "700" - }, - { - "type": "text", - "id": "SMCcS", - "fill": "#9CA3AF", - "content": "2.3 KB", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "YeOv5", - "width": "fill_container", - "height": 148, - "fill": "$surface-inverse", - "cornerRadius": 14, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "effect": { - "type": "shadow", - "shadowType": "outer", - "color": "#5C452014", - "offset": { - "x": 0, - "y": 3 - }, - "blur": 12 - }, - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "c1FEEy", - "layoutPosition": "absolute", - "x": 10, - "y": 10, - "fill": "#16A34A", - "cornerRadius": 6, - "padding": [ - 3, - 7 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "znWfy", - "fill": "#FFFFFF", - "content": "NGINX", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "PUINb", - "layoutPosition": "absolute", - "x": 10, - "y": 36, - "clip": true, - "width": 154, - "height": 78, - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "frame", - "id": "BsbPh", - "height": 13, - "children": [ - { - "type": "text", - "id": "SDxen", - "fill": "#569CD6", - "content": "worker_processes", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "t6uLwZ", - "fill": "#B5CEA8", - "content": " 1", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "df9D1", - "fill": "#D4D4D4", - "content": ";", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "xKtEM", - "height": 13, - "children": [ - { - "type": "text", - "id": "NnuES", - "fill": "#569CD6", - "content": "events", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "WwWs0", - "fill": "#D4D4D4", - "content": " {", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "Ol2QT", - "height": 13, - "children": [ - { - "type": "text", - "id": "cPJmd", - "fill": "#569CD6", - "content": " worker_connections", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "HJ4Pi", - "fill": "#B5CEA8", - "content": " 1024", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "SEfc5", - "fill": "#D4D4D4", - "content": ";", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "HWiHU", - "height": 13, - "children": [ - { - "type": "text", - "id": "b3rNu", - "fill": "#D4D4D4", - "content": "}", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "FbDuc", - "height": 13, - "children": [ - { - "type": "text", - "id": "g6fs5G", - "fill": "#569CD6", - "content": "http", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "iyilE", - "fill": "#D4D4D4", - "content": " {", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "g0oocl", - "height": 13, - "children": [ - { - "type": "text", - "id": "MwzCy", - "fill": "#569CD6", - "content": " server", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "n1g0k", - "fill": "#D4D4D4", - "content": " {", - "fontFamily": "JetBrains Mono", - "fontSize": 9, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "rectangle", - "cornerRadius": [ - 0, - 0, - 14, - 14 - ], - "id": "LHHA9", - "layoutPosition": "absolute", - "x": 0, - "y": 116, - "fill": { - "type": "gradient", - "gradientType": "linear", - "enabled": true, - "rotation": 180, - "size": { - "height": 1 - }, - "colors": [ - { - "color": "#0A0F1400", - "position": 0 - }, - { - "color": "#0A0F14EE", - "position": 0.6 - } - ] - }, - "width": 200, - "height": 52 - }, - { - "type": "frame", - "id": "Dz2XX", - "layoutPosition": "absolute", - "x": 0, - "y": 124, - "width": 174, - "height": 40, - "layout": "vertical", - "gap": 2, - "padding": [ - 0, - 12 - ], - "justifyContent": "center", - "children": [ - { - "type": "text", - "id": "RcGdo", - "fill": "#FFFFFF", - "textGrowth": "fixed-width", - "width": 150, - "content": "nginx.conf", - "fontFamily": "Inter", - "fontSize": 13, - "fontWeight": "700" - }, - { - "type": "text", - "id": "iHS0Z", - "fill": "#9CA3AF", - "content": "1.8 KB", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "MOCoa", - "width": "fill_container", - "padding": [ - 12, - 21, - 21, - 21 - ], - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "O5gtO", - "width": "fill_container", - "height": 62, - "fill": "$surface-card", - "cornerRadius": 36, - "stroke": { - "thickness": 1, - "fill": "$border" - }, - "padding": 4, - "children": [ - { - "type": "frame", - "id": "AIvMH", - "width": "fill_container", - "height": "fill_container", - "fill": "#00000000", - "cornerRadius": 26, - "layout": "vertical", - "gap": 4, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "nx7rN", - "width": 18, - "height": 18, - "iconFontName": "monitor", - "iconFontFamily": "lucide", - "fill": "$font-muted" - }, - { - "type": "text", - "id": "rsaYj", - "fill": "$font-muted", - "content": "服务器", - "fontFamily": "Inter", - "fontSize": 10, - "fontWeight": "600", - "letterSpacing": 0.5 - } - ] - }, - { - "type": "frame", - "id": "nCr1z", - "width": "fill_container", - "height": "fill_container", - "fill": "$accent", - "cornerRadius": 26, - "layout": "vertical", - "gap": 4, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "q7ccx", - "width": 18, - "height": 18, - "iconFontName": "folder", - "iconFontFamily": "lucide", - "fill": "#FFFFFF" - }, - { - "type": "text", - "id": "rpKWk", - "fill": "#FFFFFF", - "content": "文件", - "fontFamily": "Inter", - "fontSize": 10, - "fontWeight": "600", - "letterSpacing": 0.5 - } - ] - }, - { - "type": "frame", - "id": "E537g7", - "width": "fill_container", - "height": "fill_container", - "fill": "#00000000", - "cornerRadius": 26, - "layout": "vertical", - "gap": 4, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "HSIxr", - "width": 18, - "height": 18, - "iconFontName": "scroll-text", - "iconFontFamily": "lucide", - "fill": "$font-muted" - }, - { - "type": "text", - "id": "jw4W4", - "fill": "$font-muted", - "content": "脚本", - "fontFamily": "Inter", - "fontSize": 10, - "fontWeight": "600", - "letterSpacing": 0.5 - } - ] - }, - { - "type": "frame", - "id": "ALcyP", - "width": "fill_container", - "height": "fill_container", - "fill": "#00000000", - "cornerRadius": 26, - "layout": "vertical", - "gap": 4, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "bDrSq", - "width": 18, - "height": 18, - "iconFontName": "settings", - "iconFontFamily": "lucide", - "fill": "$font-muted" - }, - { - "type": "text", - "id": "N6a0W", - "fill": "$font-muted", - "content": "设置", - "fontFamily": "Inter", - "fontSize": 10, - "fontWeight": "600", - "letterSpacing": 0.5 - } - ] - } - ] - } - ] - } - ] - }, { "type": "frame", "id": "TEpnn", diff --git a/mobile/lib/features/shell/editor/editor_language.dart b/mobile/lib/features/shell/editor/editor_language.dart index bb0d6b3..a4586a2 100644 --- a/mobile/lib/features/shell/editor/editor_language.dart +++ b/mobile/lib/features/shell/editor/editor_language.dart @@ -54,6 +54,13 @@ String? _fileExtension(String name) { return name.substring(dot + 1).toLowerCase(); } +String _basenameLower(String name) { + final normalized = name.replaceAll('\\', '/'); + final slash = normalized.lastIndexOf('/'); + final base = slash < 0 ? normalized : normalized.substring(slash + 1); + return base.toLowerCase(); +} + bool isKnownBinaryExtension(String name) { final ext = _fileExtension(name); if (ext == null) return false; @@ -63,6 +70,27 @@ bool isKnownBinaryExtension(String name) { bool hasFileExtension(String name) => _fileExtension(name) != null; EditorLanguage detectFromFileName(String name) { + final base = _basenameLower(name); + switch (base) { + case 'nginx.conf': + return EditorLanguage( + id: 'Nginx', + highlightMode: langNginx, + defaultIndent: 2, + ); + case 'caddyfile': + return EditorLanguage( + id: 'Caddyfile', + highlightMode: langNginx, + defaultIndent: 2, + ); + case 'dockerfile': + return EditorLanguage( + id: 'Dockerfile', + highlightMode: langDockerfile, + defaultIndent: 2, + ); + } final ext = _fileExtension(name); if (ext == null) { return _plainText; diff --git a/mobile/lib/features/shell/sftp_session_manager.dart b/mobile/lib/features/shell/sftp_session_manager.dart index e6586cd..3f1ab09 100644 --- a/mobile/lib/features/shell/sftp_session_manager.dart +++ b/mobile/lib/features/shell/sftp_session_manager.dart @@ -71,6 +71,7 @@ class SftpSessionState extends ChangeNotifier { bool loadingDirectory = false; bool showHidden = false; String? lastError; + String? connectPhase; bool get isConnected => status == SftpConnectionStatus.connected; bool get hasSelection => selectedNames.isNotEmpty; @@ -176,6 +177,7 @@ class SftpSessionManager extends ChangeNotifier { lastError: null, selectedNames: {}, ); + state.connectPhase = 'transport'; notifyListeners(); try { @@ -192,6 +194,8 @@ class SftpSessionManager extends ChangeNotifier { : null, identities: identities, ); + state.connectPhase = 'channel'; + notifyListeners(); final sftp = await client.sftp(); _connections[server.id] = _SftpConnection( client: client, @@ -199,13 +203,19 @@ class SftpSessionManager extends ChangeNotifier { transport: transport, ); - final initial = await _resolveInitialPath(sftp, config.username); - final entries = await _listDirectory(sftp, initial, state.showHidden); - final favorites = await loadFavorites?.call(server.id) ?? const []; + state.connectPhase = 'listing'; + notifyListeners(); + final results = await Future.wait([ + _resolveInitialPathAndList(sftp, config.username, state.showHidden), + _safeLoadFavorites(loadFavorites, server.id), + ]); + final listing = results[0] as _InitialListing; + final favorites = results[1] as List; + state.connectPhase = null; state.update( status: SftpConnectionStatus.connected, - currentPath: initial, - entries: entries, + currentPath: listing.path, + entries: listing.entries, favorites: favorites, loadingDirectory: false, lastError: null, @@ -215,6 +225,7 @@ class SftpSessionManager extends ChangeNotifier { return state; } catch (error) { await _connections.remove(server.id)?.close(); + state.connectPhase = null; state.update( status: SftpConnectionStatus.error, loadingDirectory: false, @@ -608,33 +619,68 @@ class SftpSessionManager extends ChangeNotifier { super.dispose(); } - Future _resolveInitialPath(SftpClient sftp, String username) async { + Future<_InitialListing> _resolveInitialPathAndList( + SftpClient sftp, + String username, + bool showHidden, + ) async { if (username == 'root') { try { - await sftp.listdir('/root'); - return '/root'; + final names = await sftp.listdir('/root'); + return _InitialListing( + path: '/root', + entries: _filterAndSort(names, showHidden), + ); } catch (_) { - return '/'; + // fall through to '/' } } try { - await sftp.listdir('/'); - return '/'; + final names = await sftp.listdir('/'); + return _InitialListing( + path: '/', + entries: _filterAndSort(names, showHidden), + ); } catch (_) { try { - return await sftp.absolute('.'); + final absolute = await sftp.absolute('.'); + final names = await sftp.listdir(absolute); + return _InitialListing( + path: absolute, + entries: _filterAndSort(names, showHidden), + ); } catch (_) { - return '~'; + final names = await sftp.listdir('.'); + return _InitialListing( + path: '~', + entries: _filterAndSort(names, showHidden), + ); } } } + Future> _safeLoadFavorites( + Future> Function(String hostId)? loader, + String hostId, + ) async { + if (loader == null) return const []; + try { + return await loader(hostId); + } catch (_) { + return const []; + } + } + Future> _listDirectory( SftpClient sftp, String path, bool showHidden, ) async { final names = await sftp.listdir(path == '~' ? '.' : path); + return _filterAndSort(names, showHidden); + } + + List _filterAndSort(List names, bool showHidden) { final entries = names .where((item) => item.filename != '.' && item.filename != '..') .where((item) => showHidden || !item.filename.startsWith('.')) @@ -834,6 +880,13 @@ class _SftpConnection { } } +class _InitialListing { + const _InitialListing({required this.path, required this.entries}); + + final String path; + final List entries; +} + extension on String { String skip(int count) { if (length <= count) return ''; diff --git a/mobile/lib/features/shell/sftp_tab.dart b/mobile/lib/features/shell/sftp_tab.dart index d9aab77..98f365c 100644 --- a/mobile/lib/features/shell/sftp_tab.dart +++ b/mobile/lib/features/shell/sftp_tab.dart @@ -128,7 +128,10 @@ class _SftpTabState extends ConsumerState { final session = manager.activeSession; if (_connecting || session?.status == SftpConnectionStatus.connecting) { - return _SftpConnectingView(server: session?.server); + return _SftpConnectingView( + server: session?.server, + phase: session?.connectPhase, + ); } if (session == null) { return ListView( @@ -758,16 +761,45 @@ class _SftpToolbar extends StatelessWidget { ? Icons.folder_outlined : Icons.insert_drive_file_outlined, favorite.path, - () { - final target = favorite.type == 'folder' - ? favorite.path - : SftpSessionManager.parentPath(favorite.path); - manager.openPath(target); - }, + () => _openFavorite(context, favorite), ), ]); } + Future _openFavorite( + BuildContext context, + SftpFavorite favorite, + ) async { + if (favorite.type == 'folder') { + await manager.openPath(favorite.path); + return; + } + final parent = SftpSessionManager.parentPath(favorite.path); + final fileName = _favoriteBasename(favorite.path); + await manager.openPath(parent); + if (!context.mounted) return; + await Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => TextEditorPage( + manager: manager, + remotePath: favorite.path, + fileName: fileName, + ), + ), + ); + if (!context.mounted) return; + await manager.refreshActive(); + } + + String _favoriteBasename(String path) { + final normalized = path.replaceAll('\\', '/'); + final trimmed = normalized.endsWith('/') && normalized.length > 1 + ? normalized.substring(0, normalized.length - 1) + : normalized; + final index = trimmed.lastIndexOf('/'); + return index < 0 ? trimmed : trimmed.substring(index + 1); + } + Future _showNameDialog( BuildContext context, { required String type, @@ -1469,13 +1501,20 @@ class _SftpFileRow extends StatelessWidget { } class _SftpConnectingView extends StatelessWidget { - const _SftpConnectingView({required this.server}); + const _SftpConnectingView({required this.server, this.phase}); final ServerModel? server; + final String? phase; @override Widget build(BuildContext context) { final l = AppLocalizations.of(context); + final phaseLabel = switch (phase) { + 'transport' => l.tr('sftp.phase.transport'), + 'channel' => l.tr('sftp.phase.channel'), + 'listing' => l.tr('sftp.phase.listing'), + _ => l.tr('sftp.connecting'), + }; return ListView( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.fromLTRB(16, 120, 16, 24), @@ -1494,7 +1533,7 @@ class _SftpConnectingView extends StatelessWidget { ), const SizedBox(height: 18), Text( - l.tr('sftp.connecting'), + phaseLabel, style: const TextStyle( color: _SftpPalette.text, fontSize: 18, diff --git a/mobile/lib/l10n/strings_en.dart b/mobile/lib/l10n/strings_en.dart index 98dbede..a41e198 100644 --- a/mobile/lib/l10n/strings_en.dart +++ b/mobile/lib/l10n/strings_en.dart @@ -148,6 +148,9 @@ const Map stringsEn = { 'sftp.statusConnected': 'Connected', 'sftp.statusDisconnected': 'Not connected', 'sftp.connecting': 'Connecting SFTP...', + 'sftp.phase.transport': 'Connecting to server...', + 'sftp.phase.channel': 'Opening SFTP channel...', + 'sftp.phase.listing': 'Reading directory...', 'sftp.emptyDirectory': 'This directory is empty.', 'sftp.upload': 'Upload', 'sftp.newItem': 'New', diff --git a/mobile/lib/l10n/strings_zh.dart b/mobile/lib/l10n/strings_zh.dart index d89e4d3..14f5ab3 100644 --- a/mobile/lib/l10n/strings_zh.dart +++ b/mobile/lib/l10n/strings_zh.dart @@ -138,6 +138,9 @@ const Map stringsZh = { 'sftp.statusConnected': '已连接', 'sftp.statusDisconnected': '未连接', 'sftp.connecting': '正在连接 SFTP...', + 'sftp.phase.transport': '正在连接服务器...', + 'sftp.phase.channel': '正在打开 SFTP 通道...', + 'sftp.phase.listing': '正在读取目录...', 'sftp.emptyDirectory': '当前目录为空', 'sftp.upload': '上传', 'sftp.newItem': '新建',