pinokiod 5.0.0 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/kernel/api/app/index.js +167 -0
- package/kernel/api/index.js +4 -0
- package/kernel/api/process/index.js +21 -0
- package/kernel/bin/browserless.js +15 -5
- package/kernel/bin/cli.js +13 -20
- package/kernel/bin/cuda.js +8 -2
- package/kernel/bin/index.js +24 -20
- package/kernel/bin/xcode-tools.js +29 -9
- package/kernel/environment.js +4 -1
- package/kernel/git.js +67 -1
- package/kernel/scripts/git/commit_files +31 -0
- package/kernel/scripts/git/reset_files +21 -0
- package/package.json +1 -1
- package/server/index.js +4 -61
- package/server/public/htmlmodal.js +12 -0
- package/server/views/app.ejs +561 -67
- package/server/views/index.ejs +4 -1
package/server/views/app.ejs
CHANGED
|
@@ -182,7 +182,9 @@ body.dark .appcanvas > aside {
|
|
|
182
182
|
background: var(--pinokio-sidebar-tabbar-bg);
|
|
183
183
|
border-bottom: 1px solid var(--pinokio-sidebar-tabbar-border);
|
|
184
184
|
*/
|
|
185
|
+
/*
|
|
185
186
|
padding: 0 12px;
|
|
187
|
+
*/
|
|
186
188
|
gap: 6px;
|
|
187
189
|
overflow: hidden;
|
|
188
190
|
--sidebar-tab-radius: 8px 8px 0 0;
|
|
@@ -1785,12 +1787,14 @@ body.dark {
|
|
|
1785
1787
|
height: 520px;
|
|
1786
1788
|
overflow: hidden;
|
|
1787
1789
|
display: flex;
|
|
1790
|
+
min-height: 0;
|
|
1788
1791
|
}
|
|
1789
1792
|
|
|
1790
1793
|
.pinokio-git-diff-main-container {
|
|
1791
1794
|
display: flex;
|
|
1792
1795
|
flex: 1;
|
|
1793
1796
|
height: 100%;
|
|
1797
|
+
min-height: 0;
|
|
1794
1798
|
backdrop-filter: blur(14px);
|
|
1795
1799
|
}
|
|
1796
1800
|
|
|
@@ -1802,16 +1806,16 @@ body.dark {
|
|
|
1802
1806
|
}
|
|
1803
1807
|
|
|
1804
1808
|
.pinokio-git-diff-file-item-row {
|
|
1805
|
-
display:
|
|
1806
|
-
|
|
1807
|
-
align-items:
|
|
1808
|
-
gap:
|
|
1809
|
+
display: grid;
|
|
1810
|
+
grid-template-columns: auto 1fr auto;
|
|
1811
|
+
align-items: center;
|
|
1812
|
+
gap: 8px;
|
|
1809
1813
|
width: 100%;
|
|
1810
1814
|
border: none;
|
|
1811
1815
|
background: transparent;
|
|
1812
1816
|
color: var(--pinokio-diff-sidebar-text);
|
|
1813
1817
|
font-size: 13px;
|
|
1814
|
-
padding: 10px
|
|
1818
|
+
padding: 10px 12px;
|
|
1815
1819
|
text-align: left;
|
|
1816
1820
|
cursor: pointer;
|
|
1817
1821
|
border-left: 3px solid transparent;
|
|
@@ -1819,6 +1823,35 @@ body.dark {
|
|
|
1819
1823
|
appearance: none;
|
|
1820
1824
|
}
|
|
1821
1825
|
|
|
1826
|
+
.pinokio-git-diff-file-checkbox {
|
|
1827
|
+
width: 18px;
|
|
1828
|
+
height: 18px;
|
|
1829
|
+
cursor: pointer;
|
|
1830
|
+
appearance: none;
|
|
1831
|
+
border: 1px solid #6b7280;
|
|
1832
|
+
border-radius: 4px;
|
|
1833
|
+
background: #f6f7fb;
|
|
1834
|
+
display: inline-grid;
|
|
1835
|
+
place-items: center;
|
|
1836
|
+
position: relative;
|
|
1837
|
+
margin-right: 2px;
|
|
1838
|
+
}
|
|
1839
|
+
.pinokio-git-diff-file-checkbox:checked {
|
|
1840
|
+
background: #2563eb;
|
|
1841
|
+
border-color: #1d4ed8;
|
|
1842
|
+
}
|
|
1843
|
+
.pinokio-git-diff-file-checkbox:checked::after {
|
|
1844
|
+
content: "✓";
|
|
1845
|
+
font-size: 13px;
|
|
1846
|
+
color: #fff;
|
|
1847
|
+
}
|
|
1848
|
+
.pinokio-git-diff-select-all {
|
|
1849
|
+
border-bottom: 1px solid var(--pinokio-diff-sidebar-border);
|
|
1850
|
+
position: sticky;
|
|
1851
|
+
top: 40px;
|
|
1852
|
+
background: #f8fafc;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1822
1855
|
.pinokio-git-diff-file-item-row .pinokio-git-diff-file {
|
|
1823
1856
|
font-weight: 600;
|
|
1824
1857
|
white-space: nowrap;
|
|
@@ -1839,13 +1872,16 @@ body.dark {
|
|
|
1839
1872
|
}
|
|
1840
1873
|
|
|
1841
1874
|
.pinokio-git-diff-file-item-row.pinokio-active-file-item {
|
|
1842
|
-
background:
|
|
1843
|
-
border-left-color:
|
|
1875
|
+
background: #eef2ff;
|
|
1876
|
+
border-left-color: #2563eb;
|
|
1844
1877
|
color: var(--pinokio-diff-sidebar-active-color);
|
|
1845
1878
|
}
|
|
1846
1879
|
|
|
1847
1880
|
.pinokio-git-diff-file-item-row.pinokio-active-file-item .pinokio-git-diff-status {
|
|
1848
|
-
color:
|
|
1881
|
+
color: #374151;
|
|
1882
|
+
}
|
|
1883
|
+
.pinokio-git-diff-file-item-row.pinokio-active-file-item .pinokio-git-diff-file-checkbox {
|
|
1884
|
+
border-color: #1d4ed8;
|
|
1849
1885
|
}
|
|
1850
1886
|
|
|
1851
1887
|
.pinokio-git-diff-file-item-row:focus-visible {
|
|
@@ -1859,11 +1895,99 @@ body.dark {
|
|
|
1859
1895
|
flex: 1;
|
|
1860
1896
|
background: var(--pinokio-diff-viewer-bg);
|
|
1861
1897
|
color: var(--pinokio-diff-viewer-text);
|
|
1862
|
-
|
|
1898
|
+
display: flex;
|
|
1899
|
+
flex-direction: column;
|
|
1900
|
+
overflow: hidden;
|
|
1863
1901
|
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
1864
1902
|
font-size: 13px;
|
|
1865
1903
|
line-height: 1.5;
|
|
1866
1904
|
}
|
|
1905
|
+
.pinokio-git-diff-viewer-header {
|
|
1906
|
+
display: flex;
|
|
1907
|
+
align-items: center;
|
|
1908
|
+
justify-content: space-between;
|
|
1909
|
+
gap: 12px;
|
|
1910
|
+
padding: 8px 12px;
|
|
1911
|
+
border-bottom: 1px solid var(--pinokio-diff-sidebar-border);
|
|
1912
|
+
background: var(--pinokio-diff-viewer-bg);
|
|
1913
|
+
position: sticky;
|
|
1914
|
+
top: 0;
|
|
1915
|
+
z-index: 1;
|
|
1916
|
+
}
|
|
1917
|
+
.pinokio-git-diff-viewer-title {
|
|
1918
|
+
font-weight: 600;
|
|
1919
|
+
overflow: hidden;
|
|
1920
|
+
text-overflow: ellipsis;
|
|
1921
|
+
white-space: nowrap;
|
|
1922
|
+
}
|
|
1923
|
+
.pinokio-git-diff-open-file {
|
|
1924
|
+
display: inline-flex;
|
|
1925
|
+
align-items: center;
|
|
1926
|
+
gap: 6px;
|
|
1927
|
+
padding: 8px 12px;
|
|
1928
|
+
border-radius: 8px;
|
|
1929
|
+
border: 1px solid #d1d5db;
|
|
1930
|
+
background: #f9fafb;
|
|
1931
|
+
color: inherit;
|
|
1932
|
+
text-decoration: none;
|
|
1933
|
+
font-weight: 600;
|
|
1934
|
+
font-size: 12px;
|
|
1935
|
+
font-family: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
1936
|
+
}
|
|
1937
|
+
.pinokio-git-diff-open-file:hover {
|
|
1938
|
+
background: #eef2ff;
|
|
1939
|
+
border-color: #cbd5e1;
|
|
1940
|
+
}
|
|
1941
|
+
.pinokio-git-diff-bulk-bar {
|
|
1942
|
+
display: flex;
|
|
1943
|
+
align-items: center;
|
|
1944
|
+
justify-content: space-between;
|
|
1945
|
+
gap: 12px;
|
|
1946
|
+
padding: 10px 12px;
|
|
1947
|
+
border-bottom: 1px solid #e5e7eb;
|
|
1948
|
+
background: #f8fafc;
|
|
1949
|
+
position: sticky;
|
|
1950
|
+
top: 0;
|
|
1951
|
+
z-index: 2;
|
|
1952
|
+
}
|
|
1953
|
+
.pinokio-git-diff-bulk-title {
|
|
1954
|
+
font-weight: 600;
|
|
1955
|
+
font-size: 13px;
|
|
1956
|
+
}
|
|
1957
|
+
.pinokio-git-diff-revert-btn {
|
|
1958
|
+
width: 100%;
|
|
1959
|
+
box-sizing: border-box;
|
|
1960
|
+
justify-content: center;
|
|
1961
|
+
display: inline-flex;
|
|
1962
|
+
align-items: center;
|
|
1963
|
+
gap: 6px;
|
|
1964
|
+
padding: 18px;
|
|
1965
|
+
border-radius: 5px;
|
|
1966
|
+
border: 1px solid #2563eb !important;
|
|
1967
|
+
background: #2563eb !important;
|
|
1968
|
+
color: #fff !important;
|
|
1969
|
+
cursor: pointer;
|
|
1970
|
+
font: inherit;
|
|
1971
|
+
}
|
|
1972
|
+
.pinokio-git-diff-revert-btn:hover {
|
|
1973
|
+
background: #1d4ed8;
|
|
1974
|
+
}
|
|
1975
|
+
.pinokio-git-diff-revert-btn:disabled {
|
|
1976
|
+
background: #e5e7eb !important;
|
|
1977
|
+
border-color: #cbd5e1 !important;
|
|
1978
|
+
color: #6b7280 !important;
|
|
1979
|
+
cursor: not-allowed;
|
|
1980
|
+
}
|
|
1981
|
+
.pinokio-git-diff-revert-btn, .pinokio-save-version-btn {
|
|
1982
|
+
font-family: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
1983
|
+
font-weight: 600;
|
|
1984
|
+
}
|
|
1985
|
+
.pinokio-git-diff-viewer-body {
|
|
1986
|
+
padding: 10px;
|
|
1987
|
+
overflow: auto;
|
|
1988
|
+
flex: 1 1 auto;
|
|
1989
|
+
min-height: 0;
|
|
1990
|
+
}
|
|
1867
1991
|
|
|
1868
1992
|
.pinokio-git-diff-empty-state {
|
|
1869
1993
|
display: grid;
|
|
@@ -1874,6 +1998,58 @@ body.dark {
|
|
|
1874
1998
|
text-align: center;
|
|
1875
1999
|
padding: 20px;
|
|
1876
2000
|
}
|
|
2001
|
+
|
|
2002
|
+
body.dark .pinokio-git-diff-file-list-panel {
|
|
2003
|
+
background: #0f172a;
|
|
2004
|
+
border-right-color: #1f2937;
|
|
2005
|
+
}
|
|
2006
|
+
body.dark .pinokio-git-diff-file-item-row {
|
|
2007
|
+
color: #e2e8f0;
|
|
2008
|
+
}
|
|
2009
|
+
body.dark .pinokio-git-diff-file-item-row:hover {
|
|
2010
|
+
background: #111827;
|
|
2011
|
+
border-left-color: #3b82f6;
|
|
2012
|
+
}
|
|
2013
|
+
body.dark .pinokio-git-diff-file-item-row.pinokio-active-file-item {
|
|
2014
|
+
background: rgba(59, 130, 246, 0.15);
|
|
2015
|
+
border-left-color: #60a5fa;
|
|
2016
|
+
}
|
|
2017
|
+
body.dark .pinokio-git-diff-file-item-row.pinokio-active-file-item .pinokio-git-diff-status {
|
|
2018
|
+
color: #cbd5e1;
|
|
2019
|
+
}
|
|
2020
|
+
body.dark .pinokio-git-diff-file-checkbox {
|
|
2021
|
+
border-color: #475569;
|
|
2022
|
+
background: #0b1220;
|
|
2023
|
+
}
|
|
2024
|
+
body.dark .pinokio-git-diff-file-checkbox:checked {
|
|
2025
|
+
background: #3b82f6;
|
|
2026
|
+
border-color: #2563eb;
|
|
2027
|
+
}
|
|
2028
|
+
body.dark .pinokio-git-diff-select-all {
|
|
2029
|
+
background: #0f172a;
|
|
2030
|
+
border-bottom-color: #1f2937;
|
|
2031
|
+
}
|
|
2032
|
+
body.dark .pinokio-git-diff-bulk-bar {
|
|
2033
|
+
background: #0f172a;
|
|
2034
|
+
border-bottom-color: #1f2937;
|
|
2035
|
+
}
|
|
2036
|
+
body.dark .pinokio-git-diff-open-file {
|
|
2037
|
+
border-color: #334155;
|
|
2038
|
+
background: #0b1220;
|
|
2039
|
+
color: #e2e8f0;
|
|
2040
|
+
}
|
|
2041
|
+
body.dark .pinokio-git-diff-open-file:hover {
|
|
2042
|
+
background: #1e293b;
|
|
2043
|
+
border-color: #475569;
|
|
2044
|
+
}
|
|
2045
|
+
body.dark .pinokio-git-diff-viewer-panel,
|
|
2046
|
+
body.dark .pinokio-git-diff-viewer-header {
|
|
2047
|
+
background: #0b1220;
|
|
2048
|
+
color: #e2e8f0;
|
|
2049
|
+
}
|
|
2050
|
+
body.dark .pinokio-git-diff-viewer-header {
|
|
2051
|
+
border-bottom-color: #1f2937;
|
|
2052
|
+
}
|
|
1877
2053
|
.pinokio-no-changes-popup.swal2-popup {
|
|
1878
2054
|
background: var(--pinokio-modal-bg) !important;
|
|
1879
2055
|
border-radius: 20px !important;
|
|
@@ -2530,26 +2706,33 @@ body.dark .pinokio-fork-dropdown-remote, body.dark .pinokio-publish-dropdown-rem
|
|
|
2530
2706
|
|
|
2531
2707
|
.pinokio-commit-message-input {
|
|
2532
2708
|
flex: 1;
|
|
2709
|
+
min-height: 44px;
|
|
2533
2710
|
}
|
|
2534
2711
|
|
|
2535
2712
|
.pinokio-save-version-btn {
|
|
2536
|
-
padding:
|
|
2537
|
-
|
|
2538
|
-
border:
|
|
2539
|
-
|
|
2540
|
-
|
|
2713
|
+
padding: 12px 18px;
|
|
2714
|
+
min-height: 44px;
|
|
2715
|
+
border-radius: 10px;
|
|
2716
|
+
border: 1px solid #2563eb !important;
|
|
2717
|
+
background: #2563eb !important;
|
|
2718
|
+
color: #fff !important;
|
|
2541
2719
|
font-weight: 600;
|
|
2542
2720
|
cursor: pointer;
|
|
2543
2721
|
}
|
|
2544
2722
|
|
|
2545
2723
|
.pinokio-save-version-btn:hover {
|
|
2546
|
-
|
|
2547
|
-
box-shadow: 0 14px 32px rgba(16, 185, 129, 0.35);
|
|
2724
|
+
background: #1d4ed8;
|
|
2548
2725
|
}
|
|
2549
2726
|
|
|
2550
2727
|
.pinokio-save-version-btn:active {
|
|
2551
2728
|
transform: translateY(0);
|
|
2552
2729
|
}
|
|
2730
|
+
.pinokio-save-version-btn:disabled {
|
|
2731
|
+
background: #e5e7eb;
|
|
2732
|
+
border-color: #cbd5e1;
|
|
2733
|
+
color: #6b7280;
|
|
2734
|
+
cursor: not-allowed;
|
|
2735
|
+
}
|
|
2553
2736
|
|
|
2554
2737
|
.pinokio-history-empty {
|
|
2555
2738
|
display: grid;
|
|
@@ -2847,6 +3030,7 @@ body.dark .pinokio-fork-dropdown-remote, body.dark .pinokio-publish-dropdown-rem
|
|
|
2847
3030
|
}
|
|
2848
3031
|
|
|
2849
3032
|
.pinokio-diff-code-line-content {
|
|
3033
|
+
box-sizing: border-box;
|
|
2850
3034
|
display: block;
|
|
2851
3035
|
width: 100%;
|
|
2852
3036
|
padding: 6px 14px;
|
|
@@ -3040,6 +3224,10 @@ body.dark .pinokio-fork-dropdown-remote, body.dark .pinokio-publish-dropdown-rem
|
|
|
3040
3224
|
}
|
|
3041
3225
|
}
|
|
3042
3226
|
*/
|
|
3227
|
+
.meta-icon {
|
|
3228
|
+
width: 30px;
|
|
3229
|
+
height: 30px;
|
|
3230
|
+
}
|
|
3043
3231
|
</style>
|
|
3044
3232
|
<link href="/app.css" rel="stylesheet"/>
|
|
3045
3233
|
<link href="/tab-link-popover.css" rel="stylesheet"/>
|
|
@@ -3115,6 +3303,9 @@ body.dark .pinokio-fork-dropdown-remote, body.dark .pinokio-publish-dropdown-rem
|
|
|
3115
3303
|
<% if (type !== 'files') { %>
|
|
3116
3304
|
<aside class='active'>
|
|
3117
3305
|
<div class='menu-container'>
|
|
3306
|
+
<% if (config.icon) { %>
|
|
3307
|
+
<img class='meta-icon' src="<%=config.icon%>"/>
|
|
3308
|
+
<% } %>
|
|
3118
3309
|
<div class='m n system' data-type="n">
|
|
3119
3310
|
<%if (type==='browse') { %>
|
|
3120
3311
|
<a id='devtab' data-mode="refresh" target="<%=dev_link%>" href="<%=dev_link%>" class="btn frame-link selected" data-index="10">
|
|
@@ -3171,11 +3362,6 @@ body.dark .pinokio-fork-dropdown-remote, body.dark .pinokio-publish-dropdown-rem
|
|
|
3171
3362
|
<div class='container'>
|
|
3172
3363
|
<% if (type === "browse") { %>
|
|
3173
3364
|
<div id='fs-status' data-workspace="<%=name%>" data-create-uri="<%=git_create_url%>" data-history-uri="<%=git_history_url%>" data-status-uri="<%=git_status_url%>" data-uri="<%=git_monitor_url%>" data-push-uri="<%=git_push_url%>" data-fork-uri="<%=git_fork_url%>">
|
|
3174
|
-
<div class="app-info" title="<%=config.title || name%>">
|
|
3175
|
-
<div class="app-info-card">
|
|
3176
|
-
<img src="<%= config.icon %>" onerror="this.onerror=null; this.src='/pinokio-black.png'" alt="Project icon">
|
|
3177
|
-
</div>
|
|
3178
|
-
</div>
|
|
3179
3365
|
<!--
|
|
3180
3366
|
<div class='fs-status-dropdown nested-menu git blue'>
|
|
3181
3367
|
<button type='button' class='fs-status-btn frame-link reveal'>
|
|
@@ -5780,6 +5966,28 @@ const rerenderMenuSection = (container, html) => {
|
|
|
5780
5966
|
})
|
|
5781
5967
|
}
|
|
5782
5968
|
|
|
5969
|
+
const isUntrackedStatus = (status) => {
|
|
5970
|
+
const s = (status || '').toLowerCase()
|
|
5971
|
+
return s.includes('new') || s.includes('add') || s.includes('untracked')
|
|
5972
|
+
}
|
|
5973
|
+
|
|
5974
|
+
const escapePathForShell = (value) => {
|
|
5975
|
+
if (typeof value !== 'string') return ''
|
|
5976
|
+
// Escape quotes and dollars/backticks to reduce shell injection risk
|
|
5977
|
+
const escaped = value.replace(/(["`$\\])/g, '\\$1')
|
|
5978
|
+
return `"${escaped}"`
|
|
5979
|
+
}
|
|
5980
|
+
|
|
5981
|
+
const buildPathArgs = (paths) => {
|
|
5982
|
+
if (!Array.isArray(paths) || paths.length === 0) {
|
|
5983
|
+
return ''
|
|
5984
|
+
}
|
|
5985
|
+
return paths
|
|
5986
|
+
.filter(Boolean)
|
|
5987
|
+
.map((p) => escapePathForShell(String(p)))
|
|
5988
|
+
.join(' ')
|
|
5989
|
+
}
|
|
5990
|
+
|
|
5783
5991
|
function getRepoListSnapshot() {
|
|
5784
5992
|
if (Array.isArray(lastRepoList) && lastRepoList.length > 0) {
|
|
5785
5993
|
return lastRepoList.slice()
|
|
@@ -6652,6 +6860,7 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6652
6860
|
}
|
|
6653
6861
|
|
|
6654
6862
|
let messageListener = null
|
|
6863
|
+
let reopenDiffOnCallback = false
|
|
6655
6864
|
|
|
6656
6865
|
const showIframeView = (src) => {
|
|
6657
6866
|
const iframeMarkup = `<iframe src="${src}" frameborder="0"></iframe>`
|
|
@@ -6714,7 +6923,13 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6714
6923
|
if (typeof check_git === 'function') {
|
|
6715
6924
|
check_git()
|
|
6716
6925
|
}
|
|
6717
|
-
|
|
6926
|
+
if (reopenDiffOnCallback && typeof showGitDiffModal === 'function') {
|
|
6927
|
+
reopenDiffOnCallback = false
|
|
6928
|
+
showGitDiffModal({ forceRefresh: true })
|
|
6929
|
+
} else {
|
|
6930
|
+
reopenDiffOnCallback = false
|
|
6931
|
+
}
|
|
6932
|
+
|
|
6718
6933
|
// Close the modal
|
|
6719
6934
|
Swal.close()
|
|
6720
6935
|
|
|
@@ -6951,17 +7166,13 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6951
7166
|
else statusCounts.modified += 1
|
|
6952
7167
|
})
|
|
6953
7168
|
|
|
6954
|
-
|
|
6955
|
-
if (statusCounts.added) badgeFragments.push(`<span class="pinokio-pill"><i class="fa-solid fa-plus"></i>${statusCounts.added} added</span>`)
|
|
6956
|
-
if (statusCounts.modified) badgeFragments.push(`<span class="pinokio-pill"><i class="fa-solid fa-pen"></i>${statusCounts.modified} updated</span>`)
|
|
6957
|
-
if (statusCounts.deleted) badgeFragments.push(`<span class="pinokio-pill"><i class="fa-solid fa-trash"></i>${statusCounts.deleted} deleted</span>`)
|
|
6958
|
-
if (statusCounts.renamed) badgeFragments.push(`<span class="pinokio-pill"><i class="fa-solid fa-arrow-right-arrow-left"></i>${statusCounts.renamed} renamed</span>`)
|
|
6959
|
-
|
|
6960
|
-
const commitSection = showSaveButton ? `
|
|
7169
|
+
const commitSection = showSaveButton ? `
|
|
6961
7170
|
<div class="pinokio-modal-footer pinokio-modal-footer--commit">
|
|
6962
7171
|
<div class="pinokio-commit-message-container">
|
|
6963
7172
|
<input type="text" class="pinokio-modal-input pinokio-commit-message-input" placeholder="Enter commit message..." value="${generateCommitMessage(changes)}">
|
|
6964
|
-
<
|
|
7173
|
+
<div class="pinokio-commit-actions">
|
|
7174
|
+
<button type="button" class="pinokio-save-version-btn">Save selected</button>
|
|
7175
|
+
</div>
|
|
6965
7176
|
</div>
|
|
6966
7177
|
</div>
|
|
6967
7178
|
` : ''
|
|
@@ -6985,15 +7196,20 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6985
7196
|
<i class="fa-solid fa-clock-rotate-left"></i> History
|
|
6986
7197
|
</button>
|
|
6987
7198
|
</div>
|
|
6988
|
-
${badgeFragments.length ? `<div class="pinokio-history-meta">${badgeFragments.join('')}</div>` : ''}
|
|
6989
7199
|
<div class="pinokio-modal-body pinokio-modal-body--diff" data-tab-panel="changes">
|
|
6990
7200
|
<div class="pinokio-git-diff-main-container">
|
|
6991
7201
|
<div class="pinokio-git-diff-file-list-panel">
|
|
7202
|
+
<div class="pinokio-git-diff-file-item-row pinokio-git-diff-select-all">
|
|
7203
|
+
<input type="checkbox" class="pinokio-git-diff-file-checkbox" data-select-all checked>
|
|
7204
|
+
<span class="pinokio-git-diff-file">Select all</span>
|
|
7205
|
+
<span></span>
|
|
7206
|
+
</div>
|
|
6992
7207
|
${changes.map((change, index) => `
|
|
6993
|
-
<
|
|
7208
|
+
<div class="pinokio-git-diff-file-item-row" role="button" tabindex="0" data-index="${index}" data-diffpath="${change.diffpath}" data-filepath="${change.file}" data-abspath="${change.path || ''}" data-status="${change.status || ''}">
|
|
7209
|
+
<input type="checkbox" class="pinokio-git-diff-file-checkbox" data-file-checkbox data-index="${index}" checked>
|
|
6994
7210
|
<span class="pinokio-git-diff-file">${change.file}</span>
|
|
6995
7211
|
<span class="pinokio-git-diff-status">${change.status}</span>
|
|
6996
|
-
</
|
|
7212
|
+
</div>
|
|
6997
7213
|
`).join('')}
|
|
6998
7214
|
</div>
|
|
6999
7215
|
<div class="pinokio-git-diff-viewer-panel">
|
|
@@ -7035,50 +7251,299 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7035
7251
|
}
|
|
7036
7252
|
},
|
|
7037
7253
|
didOpen: () => {
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
const fileItems = container.querySelectorAll('.pinokio-git-diff-file-item-row')
|
|
7254
|
+
const container = Swal.getHtmlContainer()
|
|
7255
|
+
if (!container) return
|
|
7256
|
+
const fileItems = container.querySelectorAll('.pinokio-git-diff-file-item-row[data-index]')
|
|
7257
|
+
const fileCheckboxes = container.querySelectorAll('[data-file-checkbox]')
|
|
7258
|
+
const selectAllCheckbox = container.querySelector('[data-select-all]')
|
|
7041
7259
|
const diffViewer = container.querySelector('.pinokio-git-diff-viewer-panel')
|
|
7042
7260
|
const tabButtons = container.querySelectorAll('.pinokio-modal-tab')
|
|
7043
7261
|
const tabPanels = container.querySelectorAll('[data-tab-panel]')
|
|
7044
7262
|
const historyPanel = container.querySelector('[data-tab-panel="history"]')
|
|
7045
7263
|
const commitFooter = container.querySelector('.pinokio-modal-footer--commit')
|
|
7046
7264
|
let historyLoaded = false
|
|
7265
|
+
let repoCwd = ''
|
|
7266
|
+
try {
|
|
7267
|
+
const commitUrlObj = commitUrl ? new URL(commitUrl, window.location.origin) : null
|
|
7268
|
+
repoCwd = commitUrlObj ? (commitUrlObj.searchParams.get('cwd') || '') : ''
|
|
7269
|
+
} catch (error) {
|
|
7270
|
+
repoCwd = ''
|
|
7271
|
+
}
|
|
7272
|
+
if (diffViewer && repoCwd) {
|
|
7273
|
+
diffViewer.setAttribute('data-repo-cwd', repoCwd)
|
|
7274
|
+
}
|
|
7047
7275
|
|
|
7048
7276
|
const saveBtn = container.querySelector('.pinokio-save-version-btn')
|
|
7277
|
+
const commitMessageInput = container.querySelector('.pinokio-commit-message-input')
|
|
7278
|
+
const getCommitMessage = () => commitMessageInput ? commitMessageInput.value.trim() : ''
|
|
7279
|
+
|
|
7049
7280
|
if (saveBtn) {
|
|
7050
7281
|
saveBtn.addEventListener('click', () => {
|
|
7051
|
-
const
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7282
|
+
const commitMessage = getCommitMessage()
|
|
7283
|
+
if (!commitUrl) {
|
|
7284
|
+
Swal.showValidationMessage('No commit URL available')
|
|
7285
|
+
return
|
|
7286
|
+
}
|
|
7287
|
+
const selectedEntries = getSelectedEntries()
|
|
7288
|
+
if (!selectedEntries.length) {
|
|
7289
|
+
Swal.showValidationMessage('No files selected')
|
|
7290
|
+
return
|
|
7291
|
+
}
|
|
7292
|
+
const trackedPaths = []
|
|
7293
|
+
const untrackedPaths = []
|
|
7294
|
+
selectedEntries.forEach((entry) => {
|
|
7295
|
+
if (isUntrackedStatus(entry.status)) {
|
|
7296
|
+
untrackedPaths.push(entry.path)
|
|
7297
|
+
} else {
|
|
7298
|
+
trackedPaths.push(entry.path)
|
|
7057
7299
|
}
|
|
7058
|
-
|
|
7300
|
+
})
|
|
7301
|
+
const trackedArg = buildPathArgs(trackedPaths)
|
|
7302
|
+
const untrackedArg = buildPathArgs(untrackedPaths)
|
|
7303
|
+
if (!trackedArg && !untrackedArg) {
|
|
7304
|
+
Swal.showValidationMessage('No files selected')
|
|
7305
|
+
return
|
|
7306
|
+
}
|
|
7307
|
+
|
|
7308
|
+
const commitUrlObj = new URL(commitUrl, window.location.origin)
|
|
7309
|
+
const viewerCwd = commitUrlObj.searchParams.get('cwd') || repoCwd || ''
|
|
7310
|
+
if (!viewerCwd) {
|
|
7311
|
+
Swal.showValidationMessage('Repository path unavailable')
|
|
7312
|
+
return
|
|
7313
|
+
}
|
|
7314
|
+
|
|
7315
|
+
const parts = [`/run/scripts/git/commit_files.json?cwd=${encodeURIComponent(viewerCwd)}`]
|
|
7316
|
+
if (commitMessage) {
|
|
7317
|
+
parts.push(`message=${encodeURIComponent(commitMessage)}`)
|
|
7318
|
+
}
|
|
7319
|
+
if (trackedArg) {
|
|
7320
|
+
parts.push(`paths=${encodeURIComponent(trackedArg)}`)
|
|
7321
|
+
}
|
|
7322
|
+
if (untrackedArg) {
|
|
7323
|
+
parts.push(`untracked_paths=${encodeURIComponent(untrackedArg)}`)
|
|
7324
|
+
}
|
|
7325
|
+
parts.push('callback_target=parent')
|
|
7326
|
+
parts.push('callback=$location.href')
|
|
7327
|
+
const url = parts.join('&')
|
|
7328
|
+
showIframeView(url)
|
|
7329
|
+
})
|
|
7330
|
+
}
|
|
7331
|
+
|
|
7332
|
+
const fileItemsArray = Array.from(fileItems)
|
|
7333
|
+
const checkboxMap = new Map()
|
|
7334
|
+
fileCheckboxes.forEach((cb) => {
|
|
7335
|
+
const idx = Number(cb.getAttribute('data-index') || '-1')
|
|
7336
|
+
checkboxMap.set(idx, cb)
|
|
7337
|
+
})
|
|
7338
|
+
const selectedIndices = new Set(fileItemsArray.map((btn) => Number(btn.getAttribute('data-index') || '-1')))
|
|
7339
|
+
let lastSelectedIndex = null
|
|
7340
|
+
|
|
7341
|
+
const applySelectionClasses = () => {
|
|
7342
|
+
fileItemsArray.forEach((btn) => {
|
|
7343
|
+
const idx = Number(btn.getAttribute('data-index') || '-1')
|
|
7344
|
+
const isSelected = selectedIndices.has(idx)
|
|
7345
|
+
btn.classList.toggle('pinokio-active-file-item', isSelected)
|
|
7346
|
+
const cb = checkboxMap.get(idx)
|
|
7347
|
+
if (cb) {
|
|
7348
|
+
cb.checked = isSelected
|
|
7349
|
+
}
|
|
7350
|
+
})
|
|
7351
|
+
if (selectAllCheckbox) {
|
|
7352
|
+
const total = fileItemsArray.length
|
|
7353
|
+
const selectedCount = selectedIndices.size
|
|
7354
|
+
selectAllCheckbox.indeterminate = selectedCount > 0 && selectedCount < total
|
|
7355
|
+
selectAllCheckbox.checked = selectedCount === total
|
|
7356
|
+
}
|
|
7357
|
+
updateBulkBar()
|
|
7358
|
+
}
|
|
7359
|
+
|
|
7360
|
+
const getSelectedEntries = () => {
|
|
7361
|
+
const entries = []
|
|
7362
|
+
fileItemsArray.forEach((btn) => {
|
|
7363
|
+
const idx = Number(btn.getAttribute('data-index') || '-1')
|
|
7364
|
+
if (!selectedIndices.has(idx)) return
|
|
7365
|
+
const status = btn.getAttribute('data-status') || ''
|
|
7366
|
+
const filePath = btn.getAttribute('data-filepath') || ''
|
|
7367
|
+
const absPath = btn.getAttribute('data-abspath') || ''
|
|
7368
|
+
const pathValue = absPath || filePath
|
|
7369
|
+
if (!pathValue) return
|
|
7370
|
+
const entry = { status, filePath, path: pathValue }
|
|
7371
|
+
entries.push(entry)
|
|
7372
|
+
})
|
|
7373
|
+
return entries
|
|
7374
|
+
}
|
|
7375
|
+
|
|
7376
|
+
const fileListPanel = container.querySelector('.pinokio-git-diff-file-list-panel')
|
|
7377
|
+
const bulkResetButton = document.createElement('button')
|
|
7378
|
+
bulkResetButton.type = 'button'
|
|
7379
|
+
bulkResetButton.className = 'pinokio-git-diff-revert-btn pinokio-git-diff-bulk-btn'
|
|
7380
|
+
bulkResetButton.disabled = true
|
|
7381
|
+
bulkResetButton.innerHTML = `<i class="fa-solid fa-arrow-rotate-left"></i> Reset selected`
|
|
7382
|
+
const bulkResetContainer = document.createElement('div')
|
|
7383
|
+
bulkResetContainer.className = 'pinokio-git-diff-bulk-bar'
|
|
7384
|
+
bulkResetContainer.setAttribute('data-bulk-bar', 'true')
|
|
7385
|
+
bulkResetContainer.appendChild(bulkResetButton)
|
|
7386
|
+
if (fileListPanel) {
|
|
7387
|
+
fileListPanel.insertBefore(bulkResetContainer, fileListPanel.firstChild)
|
|
7388
|
+
}
|
|
7389
|
+
|
|
7390
|
+
function updateBulkBar() {
|
|
7391
|
+
const selectedEntries = getSelectedEntries()
|
|
7392
|
+
const selectionCount = selectedEntries.length
|
|
7393
|
+
const trackedPaths = []
|
|
7394
|
+
const untrackedPaths = []
|
|
7395
|
+
selectedEntries.forEach((entry) => {
|
|
7396
|
+
if (isUntrackedStatus(entry.status)) {
|
|
7397
|
+
untrackedPaths.push(entry.path)
|
|
7059
7398
|
} else {
|
|
7060
|
-
|
|
7399
|
+
trackedPaths.push(entry.path)
|
|
7061
7400
|
}
|
|
7062
7401
|
})
|
|
7402
|
+
const trackedArg = buildPathArgs(trackedPaths)
|
|
7403
|
+
const untrackedArg = buildPathArgs(untrackedPaths)
|
|
7404
|
+
const viewerCwd = (diffViewer && diffViewer.getAttribute('data-repo-cwd')) || repoCwd || ''
|
|
7405
|
+
const hasPaths = Boolean(trackedArg || untrackedArg)
|
|
7406
|
+
const hasTarget = Boolean(viewerCwd && hasPaths && selectionCount > 0)
|
|
7407
|
+
let bulkUrl = null
|
|
7408
|
+
if (hasTarget) {
|
|
7409
|
+
const urlParts = [`/run/scripts/git/reset_files.json?cwd=${encodeURIComponent(viewerCwd)}`]
|
|
7410
|
+
if (trackedArg) urlParts.push(`tracked_paths=${encodeURIComponent(trackedArg)}`)
|
|
7411
|
+
if (untrackedArg) urlParts.push(`untracked_paths=${encodeURIComponent(untrackedArg)}`)
|
|
7412
|
+
urlParts.push('callback_target=parent')
|
|
7413
|
+
urlParts.push('callback=$location.href')
|
|
7414
|
+
bulkUrl = urlParts.join('&')
|
|
7415
|
+
}
|
|
7416
|
+
bulkResetButton.textContent = `Reset selected (${selectionCount})`
|
|
7417
|
+
bulkResetButton.disabled = selectionCount === 0
|
|
7418
|
+
bulkResetButton.onclick = null
|
|
7419
|
+
bulkResetButton.onclick = () => {
|
|
7420
|
+
if (selectionCount === 0) return
|
|
7421
|
+
if (!viewerCwd || !hasPaths || !bulkUrl) {
|
|
7422
|
+
Swal.showValidationMessage('Cannot reset: missing repository context or paths')
|
|
7423
|
+
return
|
|
7424
|
+
}
|
|
7425
|
+
const confirmed = confirm(`Reset ${selectionCount} selected file${selectionCount === 1 ? '' : 's'}?`)
|
|
7426
|
+
if (!confirmed) return
|
|
7427
|
+
reopenDiffOnCallback = true
|
|
7428
|
+
showIframeView(bulkUrl)
|
|
7429
|
+
}
|
|
7063
7430
|
}
|
|
7064
7431
|
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7432
|
+
const renderFileDiff = async (item) => {
|
|
7433
|
+
const diffpath = item.getAttribute('data-diffpath')
|
|
7434
|
+
const filePath = item.getAttribute('data-filepath') || ''
|
|
7435
|
+
const titleText = escapeHtml(filePath || 'Selected file')
|
|
7436
|
+
const openHref = (repoParam && filePath)
|
|
7437
|
+
? `/api/${encodeRepoPath(repoParam)}/${filePath.split('/').map(encodeURIComponent).join('/') }?fs=view`
|
|
7438
|
+
: null
|
|
7439
|
+
|
|
7440
|
+
const headerHtml = `
|
|
7441
|
+
<div class="pinokio-git-diff-viewer-header">
|
|
7442
|
+
<div class="pinokio-git-diff-viewer-title">${titleText}</div>
|
|
7443
|
+
${openHref ? `
|
|
7444
|
+
<button type="button" class="pinokio-git-diff-open-file" data-open-repo="${escapeHtml(repoParam || '')}" data-open-relpath="${escapeHtml(filePath || '')}">
|
|
7445
|
+
<i class="fa-solid fa-folder-open"></i>
|
|
7446
|
+
Open in explorer
|
|
7447
|
+
</button>
|
|
7448
|
+
` : ''}
|
|
7449
|
+
</div>
|
|
7450
|
+
`
|
|
7451
|
+
|
|
7452
|
+
diffViewer.innerHTML = `${headerHtml}<div class="pinokio-git-diff-viewer-body"><div class="pinokio-git-diff-empty-state">Loading…</div></div>`
|
|
7453
|
+
const diffBody = diffViewer.querySelector('.pinokio-git-diff-viewer-body')
|
|
7454
|
+
try {
|
|
7455
|
+
const diffRes = await fetch(diffpath)
|
|
7456
|
+
const diffJson = await diffRes.json()
|
|
7457
|
+
renderDiff(diffJson, diffBody)
|
|
7458
|
+
const openBtn = diffViewer.querySelector('.pinokio-git-diff-open-file')
|
|
7459
|
+
if (openBtn) {
|
|
7460
|
+
openBtn.addEventListener('click', async () => {
|
|
7461
|
+
const repoKey = openBtn.getAttribute('data-open-repo') || repoParam || ''
|
|
7462
|
+
const rel = openBtn.getAttribute('data-open-relpath') || ''
|
|
7463
|
+
if (!repoKey || !rel) return
|
|
7464
|
+
const encodedRepo = encodeRepoPath(repoKey)
|
|
7465
|
+
const encodedRel = rel.split('/').map(encodeURIComponent).join('/')
|
|
7466
|
+
const url = `/api/${encodedRepo}/${encodedRel}?fs=view`
|
|
7467
|
+
try {
|
|
7468
|
+
await fetch(url)
|
|
7469
|
+
} catch (error) {
|
|
7470
|
+
console.error('Failed to open in explorer', error)
|
|
7471
|
+
}
|
|
7472
|
+
})
|
|
7473
|
+
}
|
|
7474
|
+
} catch (error) {
|
|
7475
|
+
console.error('Error fetching diff:', error)
|
|
7476
|
+
if (diffBody) {
|
|
7477
|
+
diffBody.innerHTML = '<div class="pinokio-git-diff-empty-state">Error loading diff</div>'
|
|
7478
|
+
}
|
|
7479
|
+
}
|
|
7480
|
+
}
|
|
7481
|
+
|
|
7482
|
+
fileItemsArray.forEach(item => {
|
|
7483
|
+
item.addEventListener('click', async (event) => {
|
|
7484
|
+
const targetIsCheckbox = event.target && event.target.hasAttribute && event.target.hasAttribute('data-file-checkbox')
|
|
7485
|
+
const index = Number(item.getAttribute('data-index') || '-1')
|
|
7486
|
+
if (!targetIsCheckbox) {
|
|
7487
|
+
// Preview only
|
|
7488
|
+
lastSelectedIndex = index
|
|
7489
|
+
await renderFileDiff(item)
|
|
7490
|
+
return
|
|
7491
|
+
}
|
|
7492
|
+
const cb = checkboxMap.get(index)
|
|
7493
|
+
const isChecked = cb ? cb.checked : selectedIndices.has(index)
|
|
7494
|
+
if (isChecked) {
|
|
7495
|
+
selectedIndices.add(index)
|
|
7496
|
+
} else {
|
|
7497
|
+
selectedIndices.delete(index)
|
|
7498
|
+
}
|
|
7499
|
+
lastSelectedIndex = index
|
|
7500
|
+
applySelectionClasses()
|
|
7501
|
+
await renderFileDiff(item)
|
|
7502
|
+
})
|
|
7503
|
+
})
|
|
7504
|
+
|
|
7505
|
+
fileCheckboxes.forEach((cb) => {
|
|
7506
|
+
cb.addEventListener('click', (e) => {
|
|
7507
|
+
e.stopPropagation()
|
|
7508
|
+
})
|
|
7509
|
+
cb.addEventListener('change', async () => {
|
|
7510
|
+
const idx = Number(cb.getAttribute('data-index') || '-1')
|
|
7511
|
+
if (cb.checked) {
|
|
7512
|
+
selectedIndices.add(idx)
|
|
7513
|
+
} else {
|
|
7514
|
+
selectedIndices.delete(idx)
|
|
7515
|
+
}
|
|
7516
|
+
applySelectionClasses()
|
|
7517
|
+
const item = fileItemsArray.find((btn) => Number(btn.getAttribute('data-index') || '-1') === idx)
|
|
7518
|
+
if (item) {
|
|
7519
|
+
await renderFileDiff(item)
|
|
7078
7520
|
}
|
|
7079
7521
|
})
|
|
7080
7522
|
})
|
|
7081
7523
|
|
|
7524
|
+
if (selectAllCheckbox) {
|
|
7525
|
+
selectAllCheckbox.addEventListener('change', () => {
|
|
7526
|
+
if (selectAllCheckbox.checked) {
|
|
7527
|
+
fileItemsArray.forEach((btn) => {
|
|
7528
|
+
const idx = Number(btn.getAttribute('data-index') || '-1')
|
|
7529
|
+
selectedIndices.add(idx)
|
|
7530
|
+
})
|
|
7531
|
+
} else {
|
|
7532
|
+
selectedIndices.clear()
|
|
7533
|
+
}
|
|
7534
|
+
applySelectionClasses()
|
|
7535
|
+
const activeItem = fileItemsArray.find((btn) => btn.classList.contains('pinokio-active-file-item'))
|
|
7536
|
+
if (activeItem) {
|
|
7537
|
+
renderFileDiff(activeItem)
|
|
7538
|
+
}
|
|
7539
|
+
})
|
|
7540
|
+
selectAllCheckbox.addEventListener('click', (e) => {
|
|
7541
|
+
e.stopPropagation()
|
|
7542
|
+
})
|
|
7543
|
+
}
|
|
7544
|
+
|
|
7545
|
+
applySelectionClasses()
|
|
7546
|
+
|
|
7082
7547
|
const renderHistoryInline = (historyData) => {
|
|
7083
7548
|
if (!historyPanel) {
|
|
7084
7549
|
return
|
|
@@ -7182,7 +7647,13 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7182
7647
|
setActiveTab('changes')
|
|
7183
7648
|
|
|
7184
7649
|
if (fileItems.length) {
|
|
7185
|
-
fileItems[0]
|
|
7650
|
+
const first = fileItems[0]
|
|
7651
|
+
const idx = Number(first.getAttribute('data-index') || '-1')
|
|
7652
|
+
if (!selectedIndices.has(idx)) {
|
|
7653
|
+
selectedIndices.add(idx)
|
|
7654
|
+
applySelectionClasses()
|
|
7655
|
+
}
|
|
7656
|
+
renderFileDiff(first).catch(() => {})
|
|
7186
7657
|
}
|
|
7187
7658
|
}
|
|
7188
7659
|
})
|
|
@@ -7506,15 +7977,15 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7506
7977
|
<button class="pinokio-custom-commit-close">×</button>
|
|
7507
7978
|
</div>
|
|
7508
7979
|
<div class="pinokio-custom-commit-content">
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
<
|
|
7980
|
+
<div class="pinokio-git-diff-main-container">
|
|
7981
|
+
<div class="pinokio-git-diff-file-list-panel">
|
|
7982
|
+
${changes.map((change, index) => `
|
|
7983
|
+
<div class="pinokio-git-diff-file-item-row" role="button" tabindex="0" data-index="${index}" data-diffpath="${change.diffpath}" data-filepath="${change.file}" data-abspath="${change.path || ''}" data-status="${change.status || ''}">
|
|
7513
7984
|
<span class="pinokio-git-diff-file">${change.file}</span>
|
|
7514
7985
|
<span class="pinokio-git-diff-status">${change.status}</span>
|
|
7515
|
-
</
|
|
7986
|
+
</div>
|
|
7516
7987
|
`).join('')}
|
|
7517
|
-
|
|
7988
|
+
</div>
|
|
7518
7989
|
<div class="pinokio-git-diff-viewer-panel">
|
|
7519
7990
|
<div class="pinokio-git-diff-empty-state">Select a file to view its changes</div>
|
|
7520
7991
|
</div>
|
|
@@ -7557,6 +8028,9 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7557
8028
|
// Add file click handlers
|
|
7558
8029
|
const fileItems = overlay.querySelectorAll('.pinokio-git-diff-file-item-row')
|
|
7559
8030
|
const diffViewer = overlay.querySelector('.pinokio-git-diff-viewer-panel')
|
|
8031
|
+
if (diffViewer && commitCheckoutCwd) {
|
|
8032
|
+
diffViewer.setAttribute('data-repo-cwd', commitCheckoutCwd)
|
|
8033
|
+
}
|
|
7560
8034
|
|
|
7561
8035
|
fileItems.forEach(item => {
|
|
7562
8036
|
item.addEventListener('click', async () => {
|
|
@@ -7566,15 +8040,35 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7566
8040
|
item.classList.add('pinokio-active-file-item')
|
|
7567
8041
|
|
|
7568
8042
|
const diffpath = item.getAttribute('data-diffpath')
|
|
7569
|
-
|
|
8043
|
+
const filePath = item.getAttribute('data-filepath') || ''
|
|
8044
|
+
const titleText = escapeHtml(filePath || 'Selected file')
|
|
8045
|
+
const headerHtml = `
|
|
8046
|
+
<div class="pinokio-git-diff-viewer-header">
|
|
8047
|
+
<div class="pinokio-git-diff-viewer-title">${titleText}</div>
|
|
8048
|
+
</div>
|
|
8049
|
+
`
|
|
8050
|
+
|
|
8051
|
+
diffViewer.innerHTML = `${headerHtml}<div class="pinokio-git-diff-viewer-body"><div class="pinokio-git-diff-empty-state">Loading...</div></div>`
|
|
8052
|
+
const diffBody = diffViewer.querySelector('.pinokio-git-diff-viewer-body')
|
|
7570
8053
|
|
|
7571
8054
|
try {
|
|
7572
8055
|
const diffRes = await fetch(diffpath)
|
|
7573
8056
|
const diffData = await diffRes.json()
|
|
7574
|
-
renderDiff(diffData,
|
|
8057
|
+
renderDiff(diffData, diffBody)
|
|
8058
|
+
const resetBtn = diffViewer.querySelector('.pinokio-git-diff-revert-btn')
|
|
8059
|
+
if (resetBtn && revertUrl) {
|
|
8060
|
+
resetBtn.addEventListener('click', () => {
|
|
8061
|
+
const confirmed = confirm('Reset this file to the previous version?')
|
|
8062
|
+
if (confirmed) {
|
|
8063
|
+
showIframeView(revertUrl)
|
|
8064
|
+
}
|
|
8065
|
+
})
|
|
8066
|
+
}
|
|
7575
8067
|
} catch (error) {
|
|
7576
8068
|
console.error('Error fetching diff:', error)
|
|
7577
|
-
|
|
8069
|
+
if (diffBody) {
|
|
8070
|
+
diffBody.innerHTML = '<div class="pinokio-git-diff-empty-state">Error loading diff</div>'
|
|
8071
|
+
}
|
|
7578
8072
|
}
|
|
7579
8073
|
})
|
|
7580
8074
|
})
|