pinokiod 3.50.0 → 3.52.0

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.
Files changed (126) hide show
  1. package/3 +1 -0
  2. package/kernel/gitconfig_template +3 -1
  3. package/kernel/index.js +11 -0
  4. package/kernel/scripts/git/create +1 -2
  5. package/kernel/scripts/git/push +1 -1
  6. package/package.json +6 -2
  7. package/server/index.js +44 -16
  8. package/server/public/common.js +0 -4
  9. package/server/public/serve/directory.html +106 -0
  10. package/server/public/serve/icons/application_xp.png +0 -0
  11. package/server/public/serve/icons/application_xp_terminal.png +0 -0
  12. package/server/public/serve/icons/box.png +0 -0
  13. package/server/public/serve/icons/cd.png +0 -0
  14. package/server/public/serve/icons/controller.png +0 -0
  15. package/server/public/serve/icons/drive.png +0 -0
  16. package/server/public/serve/icons/film.png +0 -0
  17. package/server/public/serve/icons/folder.png +0 -0
  18. package/server/public/serve/icons/font.png +0 -0
  19. package/server/public/serve/icons/image.png +0 -0
  20. package/server/public/serve/icons/map.png +0 -0
  21. package/server/public/serve/icons/page.png +0 -0
  22. package/server/public/serve/icons/page_add.png +0 -0
  23. package/server/public/serve/icons/page_attach.png +0 -0
  24. package/server/public/serve/icons/page_code.png +0 -0
  25. package/server/public/serve/icons/page_copy.png +0 -0
  26. package/server/public/serve/icons/page_delete.png +0 -0
  27. package/server/public/serve/icons/page_edit.png +0 -0
  28. package/server/public/serve/icons/page_error.png +0 -0
  29. package/server/public/serve/icons/page_excel.png +0 -0
  30. package/server/public/serve/icons/page_find.png +0 -0
  31. package/server/public/serve/icons/page_gear.png +0 -0
  32. package/server/public/serve/icons/page_go.png +0 -0
  33. package/server/public/serve/icons/page_green.png +0 -0
  34. package/server/public/serve/icons/page_key.png +0 -0
  35. package/server/public/serve/icons/page_lightning.png +0 -0
  36. package/server/public/serve/icons/page_link.png +0 -0
  37. package/server/public/serve/icons/page_paintbrush.png +0 -0
  38. package/server/public/serve/icons/page_paste.png +0 -0
  39. package/server/public/serve/icons/page_red.png +0 -0
  40. package/server/public/serve/icons/page_refresh.png +0 -0
  41. package/server/public/serve/icons/page_save.png +0 -0
  42. package/server/public/serve/icons/page_white.png +0 -0
  43. package/server/public/serve/icons/page_white_acrobat.png +0 -0
  44. package/server/public/serve/icons/page_white_actionscript.png +0 -0
  45. package/server/public/serve/icons/page_white_add.png +0 -0
  46. package/server/public/serve/icons/page_white_c.png +0 -0
  47. package/server/public/serve/icons/page_white_camera.png +0 -0
  48. package/server/public/serve/icons/page_white_cd.png +0 -0
  49. package/server/public/serve/icons/page_white_code.png +0 -0
  50. package/server/public/serve/icons/page_white_code_red.png +0 -0
  51. package/server/public/serve/icons/page_white_coldfusion.png +0 -0
  52. package/server/public/serve/icons/page_white_compressed.png +0 -0
  53. package/server/public/serve/icons/page_white_copy.png +0 -0
  54. package/server/public/serve/icons/page_white_cplusplus.png +0 -0
  55. package/server/public/serve/icons/page_white_csharp.png +0 -0
  56. package/server/public/serve/icons/page_white_cup.png +0 -0
  57. package/server/public/serve/icons/page_white_database.png +0 -0
  58. package/server/public/serve/icons/page_white_delete.png +0 -0
  59. package/server/public/serve/icons/page_white_dvd.png +0 -0
  60. package/server/public/serve/icons/page_white_edit.png +0 -0
  61. package/server/public/serve/icons/page_white_error.png +0 -0
  62. package/server/public/serve/icons/page_white_excel.png +0 -0
  63. package/server/public/serve/icons/page_white_find.png +0 -0
  64. package/server/public/serve/icons/page_white_flash.png +0 -0
  65. package/server/public/serve/icons/page_white_freehand.png +0 -0
  66. package/server/public/serve/icons/page_white_gear.png +0 -0
  67. package/server/public/serve/icons/page_white_get.png +0 -0
  68. package/server/public/serve/icons/page_white_go.png +0 -0
  69. package/server/public/serve/icons/page_white_h.png +0 -0
  70. package/server/public/serve/icons/page_white_horizontal.png +0 -0
  71. package/server/public/serve/icons/page_white_key.png +0 -0
  72. package/server/public/serve/icons/page_white_lightning.png +0 -0
  73. package/server/public/serve/icons/page_white_link.png +0 -0
  74. package/server/public/serve/icons/page_white_magnify.png +0 -0
  75. package/server/public/serve/icons/page_white_medal.png +0 -0
  76. package/server/public/serve/icons/page_white_office.png +0 -0
  77. package/server/public/serve/icons/page_white_paint.png +0 -0
  78. package/server/public/serve/icons/page_white_paintbrush.png +0 -0
  79. package/server/public/serve/icons/page_white_paste.png +0 -0
  80. package/server/public/serve/icons/page_white_php.png +0 -0
  81. package/server/public/serve/icons/page_white_picture.png +0 -0
  82. package/server/public/serve/icons/page_white_powerpoint.png +0 -0
  83. package/server/public/serve/icons/page_white_put.png +0 -0
  84. package/server/public/serve/icons/page_white_ruby.png +0 -0
  85. package/server/public/serve/icons/page_white_stack.png +0 -0
  86. package/server/public/serve/icons/page_white_star.png +0 -0
  87. package/server/public/serve/icons/page_white_swoosh.png +0 -0
  88. package/server/public/serve/icons/page_white_text.png +0 -0
  89. package/server/public/serve/icons/page_white_text_width.png +0 -0
  90. package/server/public/serve/icons/page_white_tux.png +0 -0
  91. package/server/public/serve/icons/page_white_vector.png +0 -0
  92. package/server/public/serve/icons/page_white_visualstudio.png +0 -0
  93. package/server/public/serve/icons/page_white_width.png +0 -0
  94. package/server/public/serve/icons/page_white_word.png +0 -0
  95. package/server/public/serve/icons/page_white_world.png +0 -0
  96. package/server/public/serve/icons/page_white_wrench.png +0 -0
  97. package/server/public/serve/icons/page_white_zip.png +0 -0
  98. package/server/public/serve/icons/page_word.png +0 -0
  99. package/server/public/serve/icons/page_world.png +0 -0
  100. package/server/public/serve/style.css +308 -0
  101. package/server/public/style.css +41 -2
  102. package/server/serveIndex.js +691 -0
  103. package/server/views/app.ejs +310 -88
  104. package/server/views/columns.ejs +1 -1
  105. package/server/views/connect/x.ejs +1 -0
  106. package/server/views/connect.ejs +1 -0
  107. package/server/views/container.ejs +1 -0
  108. package/server/views/download.ejs +1 -0
  109. package/server/views/explore.ejs +1 -0
  110. package/server/views/form.ejs +1 -0
  111. package/server/views/frame.ejs +1 -0
  112. package/server/views/github.ejs +1 -0
  113. package/server/views/help.ejs +1 -0
  114. package/server/views/index.ejs +1 -0
  115. package/server/views/init/index.ejs +2 -1
  116. package/server/views/mini.ejs +1 -0
  117. package/server/views/net.ejs +1 -0
  118. package/server/views/network.ejs +115 -17
  119. package/server/views/prototype/index.ejs +1 -0
  120. package/server/views/review.ejs +1 -0
  121. package/server/views/rows.ejs +1 -1
  122. package/server/views/screenshots.ejs +1 -0
  123. package/server/views/settings.ejs +1 -0
  124. package/server/views/setup.ejs +1 -0
  125. package/server/views/setup_home.ejs +1 -0
  126. package/server/views/tools.ejs +1 -0
@@ -135,6 +135,9 @@ main {
135
135
  main iframe[name^=http] {
136
136
  background: white;
137
137
  }
138
+ main iframe[name^=file-browse] {
139
+ background: white;
140
+ }
138
141
  main iframe {
139
142
  width: 100%;
140
143
  height: 100%;
@@ -844,11 +847,16 @@ body.dark #fs-status {
844
847
  background: rgba(0,0,0,0.04);
845
848
  gap: 5px;
846
849
  box-sizing: border-box;
850
+ /*
847
851
  margin: 0 10px;
852
+ */
848
853
  padding: 5px;
849
854
  display: flex;
850
855
  align-items: center;
856
+ /*
851
857
  border-radius: 6px;
858
+ */
859
+ justify-content: flex-end;
852
860
  }
853
861
 
854
862
  .fs-status-btn {
@@ -857,7 +865,7 @@ body.dark #fs-status {
857
865
  padding: 8px 12px;
858
866
  cursor: pointer;
859
867
  border-radius: 4px;
860
- display: flex;
868
+ display: flex !important;
861
869
  align-items: center;
862
870
  gap: 8px;
863
871
  font-size: 14px;
@@ -892,6 +900,39 @@ body.dark .fs-status-btn:hover {
892
900
  text-align: center;
893
901
  }
894
902
 
903
+ /* Publish modal styles */
904
+ .publish-modal-container {
905
+ padding: 0 !important;
906
+ margin: 0 !important;
907
+ }
908
+
909
+ /* Remote selection modal styles */
910
+ .swal2-html-container select,
911
+ .swal2-html-container input[type="text"] {
912
+ font-family: inherit;
913
+ }
914
+
915
+ body.dark .swal2-html-container select,
916
+ body.dark .swal2-html-container input[type="text"] {
917
+ background: rgba(255, 255, 255, 0.1);
918
+ color: white;
919
+ border-color: rgba(255, 255, 255, 0.3);
920
+ }
921
+
922
+ body.dark .swal2-html-container option {
923
+ background: #2d3748;
924
+ color: white;
925
+ }
926
+
927
+ /* Checkbox styling for dark mode */
928
+ body.dark .swal2-html-container input[type="checkbox"] {
929
+ accent-color: #4a90e2;
930
+ }
931
+
932
+ body.dark .swal2-html-container label {
933
+ color: white;
934
+ }
935
+
895
936
  /* Git diff modal styles - using specific prefixed classes to avoid collisions */
896
937
  .pinokio-git-diff-modal-wrapper {
897
938
  width: 90vw !important;
@@ -1144,16 +1185,16 @@ body.dark .pinokio-commit-message-input:focus {
1144
1185
  }
1145
1186
 
1146
1187
  .pinokio-save-version-btn {
1147
- background: #1f883d;
1148
- color: white;
1149
- border: 1px solid rgba(31, 35, 40, 0.15);
1150
- border-radius: 6px;
1151
- padding: 8px 16px;
1152
- font-size: 14px;
1153
- font-weight: 500;
1154
- cursor: pointer;
1155
- transition: background-color 0.2s;
1156
- white-space: nowrap;
1188
+ background: #1f883d !important;
1189
+ color: white !important;
1190
+ border: 1px solid rgba(31, 35, 40, 0.15) !important;
1191
+ border-radius: 6px !important;
1192
+ padding: 8px 16px !important;
1193
+ font-size: 14px !important;
1194
+ font-weight: 500 !important;
1195
+ cursor: pointer !important;
1196
+ transition: background-color 0.2s !important;
1197
+ white-space: nowrap !important;
1157
1198
  }
1158
1199
 
1159
1200
  .pinokio-save-version-btn:hover {
@@ -1666,6 +1707,9 @@ body.minimized {
1666
1707
  body.minimized aside {
1667
1708
  display: none;
1668
1709
  }
1710
+ body.minimized #fs-status {
1711
+ padding-left: 55px;
1712
+ }
1669
1713
  @media only screen and (max-width: 800px) {
1670
1714
  .mode-selector .btn2 {
1671
1715
  width: unset;
@@ -1711,6 +1755,7 @@ body.minimized aside {
1711
1755
  <script src="/tippy-bundle.umd.min.js"></script>
1712
1756
  </head>
1713
1757
  <body class='<%=theme%>' data-platform="<%=platform%>" data-agent="<%=agent%>">
1758
+ <div id='dragger'></div>
1714
1759
  <header class='navheader grabbable'>
1715
1760
  <h1>
1716
1761
  <a class='home' href="/">
@@ -1822,7 +1867,7 @@ body.minimized aside {
1822
1867
  </div>
1823
1868
  <div class='menu-container'>
1824
1869
  <div class='m n system' data-type="n">
1825
- <a target="<%=src%>" href="<%=src%>" class='btn header-item frame-link' data-index="0" data-mode="refresh">
1870
+ <a id='file-browse' target="file-browse" href="<%=asset%>" class='btn header-item frame-link' data-index="0">
1826
1871
  <div class='tab'>
1827
1872
  <i class="fa-regular fa-folder-open"></i> Files
1828
1873
  </div>
@@ -1937,13 +1982,16 @@ body.minimized aside {
1937
1982
 
1938
1983
  <div class='container'>
1939
1984
  <% if (type === "browse") { %>
1940
- <div id='fs-status' data-history-uri="<%=git_history_url%>" data-uri="<%=git_monitor_url%>">
1985
+ <div id='fs-status' data-create-uri="<%=git_create_url%>" data-history-uri="<%=git_history_url%>" data-uri="<%=git_monitor_url%>" data-push-uri="<%=git_push_url%>">
1941
1986
  <button id='fs-changes-btn' class='fs-status-btn'>
1942
- <span>Changes</span>
1987
+ <span><i class="fa-solid fa-code-compare"></i> Changes</span>
1943
1988
  <div class='badge'>loading...</div>
1944
1989
  </button>
1945
1990
  <button id='fs-history-btn' class='fs-status-btn'>
1946
- <span>History</span>
1991
+ <span><i class="fa-solid fa-clock-rotate-left"></i> History</span>
1992
+ </button>
1993
+ <button id='fs-push-btn' class='fs-status-btn'>
1994
+ <span><i class="fa-brands fa-github"></i> Publish</span>
1947
1995
  </button>
1948
1996
  </div>
1949
1997
  <% } %>
@@ -1964,12 +2012,10 @@ body.minimized aside {
1964
2012
  // Try to access the iframe's document
1965
2013
  const currentSrc = iframe.src
1966
2014
  // Check if it's a chrome error page or empty
1967
- console.log({ currentSrc, originalSrc })
1968
2015
  if (currentSrc !== originalSrc &&
1969
2016
  (currentSrc.includes('chrome-error://') ||
1970
2017
  currentSrc === 'about:blank' ||
1971
2018
  currentSrc.includes('data:'))) {
1972
- console.log('Iframe failed to load, switching to fallback');
1973
2019
  iframeDoc.classList.add("hidden")
1974
2020
  Swal.fire({
1975
2021
  html: `<i class="fa-solid fa-circle-notch fa-spin"></i> Loading...`,
@@ -1981,9 +2027,7 @@ body.minimized aside {
1981
2027
  actions: "hidden"
1982
2028
  }
1983
2029
  });
1984
- console.log("retrying after 3 seconds")
1985
2030
  setTimeout(() => {
1986
- console.log("retrying")
1987
2031
  iframe.src = iframe.src
1988
2032
  }, 3000)
1989
2033
  }
@@ -1991,7 +2035,6 @@ body.minimized aside {
1991
2035
  iframe.classList.add("hidden")
1992
2036
  // Cross-origin restriction - assume it loaded successfully
1993
2037
  // if no error was thrown during the initial load
1994
- console.log("ERROR", e)
1995
2038
  Swal.fire({
1996
2039
  html: `<i class="fa-solid fa-circle-notch fa-spin"></i> Loading...`,
1997
2040
  customClass: {
@@ -2141,11 +2184,8 @@ body.minimized aside {
2141
2184
  if (selection && selection.href) {
2142
2185
  let selection_protocol = new URL(selection.href).protocol
2143
2186
  let page_protocol = new URL(location.href).protocol
2144
- console.log({ selection_protocol, page_protocol })
2145
2187
  if (selection_protocol !== page_protocol) {
2146
- console.log({ timeout_id })
2147
2188
  if (!timeout_id) {
2148
- console.log("Retrying in 3 seconds")
2149
2189
  Swal.fire({
2150
2190
  html: `<i class="fa-solid fa-circle-notch fa-spin"></i> Loading...`,
2151
2191
  customClass: {
@@ -2164,10 +2204,8 @@ body.minimized aside {
2164
2204
  }
2165
2205
  }
2166
2206
  <% } %>
2167
- console.log("renderSelection", global_selector)
2168
2207
  if (global_selector) {
2169
2208
  selection = document.querySelector(global_selector)
2170
- console.log("selection", selection)
2171
2209
  global_selector = null
2172
2210
  }
2173
2211
  if (selection || location.hash && location.hash.length > 0) {
@@ -2181,7 +2219,6 @@ body.minimized aside {
2181
2219
  } else {
2182
2220
  let type = id[0]
2183
2221
  let index = id.slice(1)
2184
- console.log({ type, index })
2185
2222
  selector = `aside .${type} [data-index='${index}']`
2186
2223
  }
2187
2224
  if (e) {
@@ -2275,7 +2312,6 @@ body.minimized aside {
2275
2312
  let hardFrames = document.querySelectorAll(".browserview iframe[name^='@']")
2276
2313
  let port = new URL(target.href).port || 80
2277
2314
  for(let frame of hardFrames) {
2278
- console.log({ src: frame.src, href: target.href, target: target.target })
2279
2315
  // Types of links in the tab
2280
2316
  //if (String(port) === "<%=port%>") {
2281
2317
  if (String(port) === String(location.port) || /https:\/\/pinokio\..*localhost/.test(origin)) {
@@ -2286,7 +2322,6 @@ body.minimized aside {
2286
2322
  if (targetPath === framePath) {
2287
2323
  let beforeName = frame.name
2288
2324
  frame.name = target.target
2289
- console.log("SET FRAME", { before: beforeName, after: frame.name, target: target.target })
2290
2325
  targetFrame = frame
2291
2326
  break
2292
2327
  }
@@ -2468,14 +2503,12 @@ body.minimized aside {
2468
2503
  // loaded[target.target] = true
2469
2504
  // }
2470
2505
  } else {
2471
- console.log("# 13")
2472
2506
  // couldn't find item,
2473
2507
  // clear the hash
2474
2508
  //
2475
2509
  location.hash = ""
2476
2510
  }
2477
2511
  } else {
2478
- console.log("# 14")
2479
2512
  document.querySelector(".container").classList.remove("active")
2480
2513
  document.querySelector("aside").classList.add("active")
2481
2514
 
@@ -2502,8 +2535,6 @@ body.minimized aside {
2502
2535
 
2503
2536
 
2504
2537
  // persist
2505
- console.log("sync tabs", tabs)
2506
-
2507
2538
  await fetch("/pinokio/tabs", {
2508
2539
  method: "POST",
2509
2540
  headers: {
@@ -2806,7 +2837,10 @@ body.minimized aside {
2806
2837
  let script = target.closest("[data-script]")
2807
2838
  if (script) {
2808
2839
  let script_id = script.getAttribute("data-script")
2809
- target.querySelector("i.fa-square").className = "fa-solid fa-check"
2840
+ try {
2841
+ target.querySelector("i.fa-square").className = "fa-solid fa-check"
2842
+ } catch (e) {
2843
+ }
2810
2844
  n.Noty({
2811
2845
  text: `stopping script`,
2812
2846
  silent: true,
@@ -2820,14 +2854,18 @@ body.minimized aside {
2820
2854
  id: script_id
2821
2855
  }
2822
2856
  }, (packet) => {
2857
+ debugger
2823
2858
  if (packet.type === "result") {
2859
+ console.log("is result")
2824
2860
  socket.close()
2861
+ debugger
2825
2862
  n.Noty({
2826
2863
  timeout: 2000,
2827
2864
  text: `stopped`,
2828
2865
  silent: true
2829
2866
  })
2830
2867
  console.log("Refresh 4")
2868
+ debugger
2831
2869
  refresh(true)
2832
2870
  }
2833
2871
  })
@@ -2981,7 +3019,6 @@ body.minimized aside {
2981
3019
 
2982
3020
  })
2983
3021
  const refresh_du = (path) => {
2984
- console.log("REFRESH DU")
2985
3022
  let url = path ? `/du/<%=name%>/${path}` : `/du/<%=name%>`
2986
3023
  let selector = `.disk-usage[data-path='/${path || ""}']`
2987
3024
  let el = document.querySelector(selector)
@@ -3003,7 +3040,6 @@ body.minimized aside {
3003
3040
  // KB
3004
3041
  val = `${Math.floor(res.du/k * 100) / 100} KB`
3005
3042
  }
3006
- console.log("DU VAL", val)
3007
3043
  el.innerHTML = val
3008
3044
  } else {
3009
3045
  }
@@ -3014,14 +3050,12 @@ body.minimized aside {
3014
3050
  let dynamic_loaded = false
3015
3051
 
3016
3052
  const try_dynamic = async () => {
3017
- console.log("Try_dynamic")
3018
3053
  let rendered
3019
3054
  let status
3020
3055
  const dynamic = await fetch("<%=dynamic%>").then((res) => {
3021
3056
  status = res.status
3022
3057
  return res.text()
3023
3058
  })
3024
- console.log("STatus", status)
3025
3059
  if (status == 500) {
3026
3060
  ModalInput({
3027
3061
  description: dynamic,
@@ -3034,7 +3068,6 @@ body.minimized aside {
3034
3068
  return
3035
3069
  }
3036
3070
  if (dynamic && dynamic.length > 0) {
3037
- console.log({ dynamic })
3038
3071
  if (document.querySelector(".dynamic .submenu")) {
3039
3072
  document.querySelector(".dynamic .submenu").innerHTML = dynamic
3040
3073
  }
@@ -3042,7 +3075,6 @@ body.minimized aside {
3042
3075
  } else {
3043
3076
  rendered = false
3044
3077
  }
3045
- console.log({ rendered, dynamic_loaded })
3046
3078
  if (rendered) {
3047
3079
  // if (dynamic_loaded) {
3048
3080
  // // already loaded, don't touch the UI
@@ -3056,7 +3088,6 @@ body.minimized aside {
3056
3088
  // }
3057
3089
  // }
3058
3090
  } else {
3059
- console.log("Not yet rendered. Try again")
3060
3091
  setTimeout(() => {
3061
3092
  try_dynamic()
3062
3093
  }, 1000)
@@ -3078,7 +3109,6 @@ body.minimized aside {
3078
3109
  status = res.status
3079
3110
  return res.text()
3080
3111
  })
3081
- console.log({ status })
3082
3112
  if (status == 500) {
3083
3113
  ModalInput({
3084
3114
  description: html,
@@ -3128,7 +3158,6 @@ body.minimized aside {
3128
3158
  fetch("/pinokio/log", {
3129
3159
  method: "post",
3130
3160
  }).then((res) => {
3131
- console.log("RES", res)
3132
3161
  let btn = document.querySelector("#genlog")
3133
3162
  let btn2 = document.querySelector("#downloadlogs")
3134
3163
  btn2.classList.remove("hidden")
@@ -3142,36 +3171,23 @@ body.minimized aside {
3142
3171
  if (init) {
3143
3172
  init.click()
3144
3173
  }
3145
- /*
3146
- window.addEventListener("hashchange", function () {
3147
- console.log("Hash changed:", location.hash);
3148
- location.reload()
3149
- });
3150
- */
3151
3174
  window.addEventListener('message', (event) => {
3152
3175
 
3153
3176
  // only process the event it's coming from pinokio
3154
3177
  let origin = event.origin
3155
- console.log("origin", origin)
3156
3178
  if (origin) {
3157
3179
  let port = new URL(origin).port || 80
3158
- console.log("port", port)
3159
3180
  if (String(port) === String(location.port) || /https:\/\/pinokio\..*localhost/.test(origin)) {
3160
3181
  //if (String(port) === "<%=port%>" || /https:\/\/pinokio\..*localhost/.test(origin)) {
3161
3182
  //if (String(port) === "<%=port%>") {
3162
- console.log("Message received from the child: ", event); // Message received from child
3163
3183
  if (event.data) {
3164
3184
  if (event.data.action) {
3165
3185
  if (event.data.action.type === "newtab") {
3166
- console.log("create tab", event.data.action.url)
3167
3186
  addTab(event.data.action.url)
3168
3187
  } else if (event.data.action.type === "title") {
3169
3188
  console.log("title", event.data)
3170
3189
  } else if (event.data.action.type === "location") {
3171
- console.log("EVENT", event)
3172
3190
  let url = event.data.action.url
3173
- console.log({ action: event.data.action })
3174
-
3175
3191
  //document.querySelector("#location").value = url
3176
3192
  let pathname = new URL(url).pathname
3177
3193
  if (pathname.startsWith("/run")) {
@@ -3181,7 +3197,6 @@ body.minimized aside {
3181
3197
  }
3182
3198
  }
3183
3199
  } else if (event.data.launch) {
3184
- debugger
3185
3200
  global_selector = `.frame-link[target="${event.data.launch.name}"]`
3186
3201
  let s = document.querySelector(global_selector)
3187
3202
  if (!s) {
@@ -3190,15 +3205,11 @@ body.minimized aside {
3190
3205
  refresh()
3191
3206
  } else if (event.data.type) {
3192
3207
  let asideHidden = (window.getComputedStyle(document.querySelector("aside")).display === "none")
3193
- console.log("asideHidden", asideHidden)
3194
3208
  if (!asideHidden) {
3195
3209
  // refresh only if aside
3196
- console.log("type", event.data.type)
3197
3210
  if (event.data.type === 'disconnect') {
3198
- console.log("Refresh 1")
3199
3211
  refresh()
3200
3212
  } else {
3201
- console.log("Refresh 2")
3202
3213
  refresh()
3203
3214
  }
3204
3215
  } else {
@@ -3210,7 +3221,6 @@ body.minimized aside {
3210
3221
  }
3211
3222
  }
3212
3223
  } else {
3213
- console.log("Refresh 3")
3214
3224
  refresh()
3215
3225
  }
3216
3226
  }
@@ -3223,14 +3233,12 @@ body.minimized aside {
3223
3233
  let frame_key = window.frameElement?.name || "";
3224
3234
 
3225
3235
  let selection_url = windowStorage.getItem(frame_key + ":url")
3226
- console.log({ frame_key, selection_url })
3227
3236
  let selection
3228
3237
  if (selection_url) {
3229
3238
  selection = document.querySelector(`[href='${selection_url}']`)
3230
3239
  } else {
3231
3240
  selection = document.querySelector("#devtab")
3232
3241
  }
3233
- console.log("CLICK", selection)
3234
3242
  if (selection) {
3235
3243
  // setTimeout(() => {
3236
3244
  selection.click()
@@ -3252,10 +3260,8 @@ body.minimized aside {
3252
3260
  /*
3253
3261
  document.addEventListener("keydown", (e) => {
3254
3262
  let size = document.querySelectorAll(".selectable").length
3255
- console.log("size", size)
3256
3263
  e = e || window.event;
3257
3264
  if (e.key === "ArrowUp") {
3258
- console.log("up arrow pressed");
3259
3265
  if (cursorIndex > 0) {
3260
3266
  cursorIndex--;
3261
3267
  } else {
@@ -3272,7 +3278,6 @@ body.minimized aside {
3272
3278
  cursorIndex = 0;
3273
3279
  }
3274
3280
  //renderCursor()
3275
- console.log("down arrow pressed");
3276
3281
  //let cursor = document.querySelector(".selectable.cursor")
3277
3282
  //cursor.scrollIntoView(false)
3278
3283
  } else if (e.key === "Enter") {
@@ -3291,24 +3296,24 @@ body.minimized aside {
3291
3296
  let gitCommitUrl = null
3292
3297
 
3293
3298
  const check_git = () => {
3294
- console.log('check_git called, fetching from:', "<%=git_monitor_url%>")
3295
3299
  fetch("<%=git_monitor_url%>").then((res) => {
3296
- console.log('check_git response status:', res.status)
3297
3300
  return res.json()
3298
3301
  }).then((res) => {
3299
- console.log('check_git response data:', res)
3300
3302
  currentChanges = res.changes || []
3301
3303
  gitCommitUrl = res.git_commit_url || null
3302
- console.log('currentChanges updated to:', currentChanges)
3304
+ const changesBtn = document.querySelector("#fs-changes-btn")
3303
3305
  const badgeElement = document.querySelector("#fs-changes-btn .badge")
3304
- console.log('Badge element found:', badgeElement)
3306
+
3305
3307
  if (res.changes && res.changes.length > 0) {
3306
- console.log('Setting badge to:', res.changes.length)
3308
+ // Show changes button and update badge
3309
+ changesBtn.style.display = 'block'
3307
3310
  badgeElement.innerHTML = `${res.changes.length}`
3308
3311
  } else {
3309
- console.log('Clearing badge')
3312
+ // Hide changes button when no changes
3313
+ changesBtn.style.display = 'none'
3310
3314
  badgeElement.innerHTML = ''
3311
3315
  }
3316
+ updatePublishButton()
3312
3317
  }).catch((error) => {
3313
3318
  console.error('check_git error:', error)
3314
3319
  })
@@ -3331,7 +3336,6 @@ body.minimized aside {
3331
3336
  }
3332
3337
 
3333
3338
  messageListener = (event) => {
3334
- console.log('Received postMessage:', event.data)
3335
3339
 
3336
3340
  // Check if event has callback data that starts with "$"
3337
3341
  if (event.data &&
@@ -3339,8 +3343,6 @@ body.minimized aside {
3339
3343
  typeof event.data.callback === 'string' &&
3340
3344
  event.data.callback.startsWith('$')) {
3341
3345
 
3342
- console.log('Callback starts with $, closing modal')
3343
-
3344
3346
  // Close the modal
3345
3347
  Swal.close()
3346
3348
 
@@ -3420,21 +3422,14 @@ body.minimized aside {
3420
3422
  }
3421
3423
 
3422
3424
  const showGitDiffModal = async (diffData = null, modalTitle = 'File Changes', showSaveButton = true) => {
3423
- console.log('showGitDiffModal called with:', { diffData, modalTitle, showSaveButton })
3424
- console.log('currentChanges:', currentChanges)
3425
-
3426
3425
  let changes = diffData ? (diffData.changes || []) : currentChanges
3427
3426
  let commitUrl = diffData ? (diffData.git_commit_url || null) : gitCommitUrl
3428
3427
 
3429
- console.log('Initial changes:', changes)
3430
-
3431
3428
  // If no diffData provided and currentChanges is empty, try to fetch fresh data
3432
3429
  if (!diffData && changes.length === 0) {
3433
- console.log('Fetching fresh data because changes is empty')
3434
3430
  try {
3435
3431
  const response = await fetch("<%=git_monitor_url%>")
3436
3432
  const freshData = await response.json()
3437
- console.log('Fresh data received:', freshData)
3438
3433
  changes = freshData.changes || []
3439
3434
  commitUrl = freshData.git_commit_url || null
3440
3435
  currentChanges = changes // Update the global variable
@@ -3444,10 +3439,8 @@ body.minimized aside {
3444
3439
  }
3445
3440
  }
3446
3441
 
3447
- console.log('Final changes before modal:', changes)
3448
3442
 
3449
3443
  if (changes.length === 0) {
3450
- console.log('No changes found - showing info dialog')
3451
3444
  Swal.fire({
3452
3445
  title: 'No Changes',
3453
3446
  text: 'No file changes detected.',
@@ -3456,8 +3449,6 @@ body.minimized aside {
3456
3449
  return
3457
3450
  }
3458
3451
 
3459
- console.log('About to show modal with changes:', changes.length)
3460
-
3461
3452
  const modalHtml = `
3462
3453
  <div class="pinokio-git-diff-main-container">
3463
3454
  <div class="pinokio-git-diff-file-list-panel">
@@ -3529,7 +3520,6 @@ body.minimized aside {
3529
3520
  }
3530
3521
 
3531
3522
  Swal.getPopup().addEventListener('message', (event) => {
3532
- console.log("EVENT", event)
3533
3523
  // if (event.data) {
3534
3524
  // if (event.data.callback) {
3535
3525
  // if (event.data.callback.startsWith("$")) {
@@ -3828,10 +3818,242 @@ body.minimized aside {
3828
3818
  `
3829
3819
  }
3830
3820
 
3821
+ const showPublishModal = () => {
3822
+ const pushUri = document.querySelector('#fs-status').getAttribute('data-push-uri')
3823
+ if (!pushUri) {
3824
+ Swal.fire({
3825
+ title: 'Error',
3826
+ text: 'Publish URL not available.',
3827
+ icon: 'error'
3828
+ })
3829
+ return
3830
+ }
3831
+
3832
+ Swal.fire({
3833
+ title: 'Publish to GitHub',
3834
+ html: `
3835
+ <div style="width: 100%; height: 400px; position: relative;">
3836
+ <iframe src="${pushUri}" style="width: 100%; height: 100%; border: none; border-radius: 8px;"></iframe>
3837
+ </div>
3838
+ `,
3839
+ width: '80%',
3840
+ showCloseButton: true,
3841
+ showConfirmButton: false,
3842
+ showCancelButton: true,
3843
+ cancelButtonText: 'Close',
3844
+ customClass: {
3845
+ htmlContainer: 'publish-modal-container'
3846
+ }
3847
+ })
3848
+ }
3849
+
3850
+ const showCreateModal = () => {
3851
+ showCreateRepoModal()
3852
+ }
3853
+
3854
+ const showRemoteSelectionModal = (remotes, pushUri) => {
3855
+ const defaultRemote = remotes.find(r => r.remote === 'origin') || remotes[0]
3856
+
3857
+ const remoteOptions = remotes.map(remote =>
3858
+ `<option value="${remote.remote}" ${remote.remote === defaultRemote.remote ? 'selected' : ''}>
3859
+ ${remote.remote} (${remote.url})
3860
+ </option>`
3861
+ ).join('')
3862
+
3863
+ Swal.fire({
3864
+ title: 'Publish to GitHub',
3865
+ html: `
3866
+ <div style="text-align: left; margin-bottom: 20px;">
3867
+ <label style="display: block; margin-bottom: 8px; font-weight: bold;">Select Remote:</label>
3868
+ <select id="remote-select" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; margin-bottom: 16px;">
3869
+ ${remoteOptions}
3870
+ </select>
3871
+
3872
+ <label style="display: block; margin-bottom: 8px; font-weight: bold;">Repository Name:</label>
3873
+ <input type="text" id="repo-name-input" placeholder="Enter repository name"
3874
+ style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;">
3875
+ </div>
3876
+ `,
3877
+ showCloseButton: true,
3878
+ showConfirmButton: true,
3879
+ showCancelButton: true,
3880
+ confirmButtonText: 'Publish',
3881
+ cancelButtonText: 'Cancel',
3882
+ preConfirm: () => {
3883
+ const selectedRemote = document.getElementById('remote-select').value
3884
+ const repoName = document.getElementById('repo-name-input').value.trim()
3885
+
3886
+ if (!repoName) {
3887
+ Swal.showValidationMessage('Repository name is required')
3888
+ return false
3889
+ }
3890
+
3891
+ return { remote: selectedRemote, name: repoName }
3892
+ }
3893
+ }).then((result) => {
3894
+ if (result.isConfirmed) {
3895
+ const { remote, name } = result.value
3896
+ showFinalPublishModal(pushUri, remote, name)
3897
+ }
3898
+ })
3899
+ }
3900
+
3901
+ const showFinalPublishModal = (pushUri, remote, name) => {
3902
+ const urlParams = new URLSearchParams()
3903
+ urlParams.append('remote', remote)
3904
+ urlParams.append('name', name)
3905
+
3906
+ const finalUri = `${pushUri}${pushUri.includes('?') ? '&' : '?'}${urlParams.toString()}`
3907
+
3908
+ Swal.fire({
3909
+ title: 'Publish to GitHub',
3910
+ html: `
3911
+ <div style="width: 100%; height: 400px; position: relative;">
3912
+ <iframe src="${finalUri}" style="width: 100%; height: 100%; border: none; border-radius: 8px;"></iframe>
3913
+ </div>
3914
+ `,
3915
+ width: '80%',
3916
+ showCloseButton: true,
3917
+ showConfirmButton: false,
3918
+ showCancelButton: true,
3919
+ cancelButtonText: 'Close',
3920
+ customClass: {
3921
+ htmlContainer: 'publish-modal-container'
3922
+ }
3923
+ })
3924
+ }
3925
+
3926
+ const showCreateRepoModal = () => {
3927
+ Swal.fire({
3928
+ title: 'Create Repository on GitHub',
3929
+ html: `
3930
+ <div style="text-align: left; margin-bottom: 20px;">
3931
+ <label style="display: block; margin-bottom: 8px; font-weight: bold;">Repository Name:</label>
3932
+ <input type="text" id="create-repo-name-input" placeholder="Enter repository name"
3933
+ style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; margin-bottom: 16px;">
3934
+
3935
+ <div style="display: flex; align-items: center; gap: 8px;">
3936
+ <input type="checkbox" id="private-checkbox" style="margin: 0;">
3937
+ <label for="private-checkbox" style="margin: 0; font-weight: normal;">Private repository</label>
3938
+ </div>
3939
+ </div>
3940
+ `,
3941
+ showCloseButton: true,
3942
+ showConfirmButton: true,
3943
+ showCancelButton: true,
3944
+ confirmButtonText: 'Create on GitHub',
3945
+ cancelButtonText: 'Cancel',
3946
+ preConfirm: () => {
3947
+ const repoName = document.getElementById('create-repo-name-input').value.trim()
3948
+ const isPrivate = document.getElementById('private-checkbox').checked
3949
+
3950
+ if (!repoName) {
3951
+ Swal.showValidationMessage('Repository name is required')
3952
+ return false
3953
+ }
3954
+
3955
+ return { name: repoName, isPrivate: isPrivate }
3956
+ }
3957
+ }).then((result) => {
3958
+ if (result.isConfirmed) {
3959
+ const { name, isPrivate } = result.value
3960
+ showCreateRepoIframeModal(name, isPrivate)
3961
+ }
3962
+ })
3963
+ }
3964
+
3965
+ const showCreateRepoIframeModal = (name, isPrivate) => {
3966
+ const createUri = document.querySelector('#fs-status').getAttribute('data-create-uri')
3967
+
3968
+ if (!createUri) {
3969
+ Swal.fire({
3970
+ title: 'Error',
3971
+ text: 'Create repository URL not available.',
3972
+ icon: 'error'
3973
+ })
3974
+ return
3975
+ }
3976
+
3977
+ const urlParams = new URLSearchParams()
3978
+ urlParams.append('name', name)
3979
+ urlParams.append('visibility', isPrivate ? 'private' : 'public')
3980
+
3981
+ const finalUri = `${createUri}${createUri.includes('?') ? '&' : '?'}${urlParams.toString()}`
3982
+
3983
+ Swal.fire({
3984
+ title: 'Create Repository on GitHub',
3985
+ html: `
3986
+ <div style="width: 100%; height: 400px; position: relative;">
3987
+ <iframe src="${finalUri}" style="width: 100%; height: 100%; border: none; border-radius: 8px;"></iframe>
3988
+ </div>
3989
+ `,
3990
+ width: '80%',
3991
+ showCloseButton: true,
3992
+ showConfirmButton: false,
3993
+ showCancelButton: true,
3994
+ cancelButtonText: 'Close',
3995
+ customClass: {
3996
+ htmlContainer: 'publish-modal-container'
3997
+ }
3998
+ })
3999
+ }
4000
+
4001
+ // Function to update publish/create button
4002
+ const updatePublishButton = async () => {
4003
+ const historyUri = document.querySelector('#fs-status').getAttribute('data-history-uri')
4004
+ const pushBtn = document.querySelector('#fs-push-btn')
4005
+
4006
+ if (!historyUri || !pushBtn) return
4007
+
4008
+ try {
4009
+ const response = await fetch(historyUri)
4010
+ const data = await response.json()
4011
+
4012
+ // Check if GitHub is connected
4013
+ if (!data.connected) {
4014
+ // Not logged in - show "Login" button
4015
+ pushBtn.innerHTML = '<span><i class="fa-brands fa-github"></i> Login</span>'
4016
+ pushBtn.removeEventListener('click', showPublishModal)
4017
+ pushBtn.removeEventListener('click', showCreateModal)
4018
+ pushBtn.addEventListener('click', () => {
4019
+ window.location.href = '/github'
4020
+ })
4021
+ return
4022
+ }
4023
+
4024
+ // GitHub is connected - show appropriate button based on remotes
4025
+ if (!data.remotes || data.remotes.length === 0) {
4026
+ // No remotes - show "Create" button
4027
+ pushBtn.innerHTML = '<span><i class="fa-brands fa-github"></i> Create</span>'
4028
+ pushBtn.removeEventListener('click', showPublishModal)
4029
+ pushBtn.removeEventListener('click', () => window.location.href = '/github')
4030
+ pushBtn.addEventListener('click', showCreateModal)
4031
+ } else {
4032
+ // Has remotes - show "Publish" button
4033
+ pushBtn.innerHTML = '<span><i class="fa-brands fa-github"></i> Publish</span>'
4034
+ pushBtn.removeEventListener('click', showCreateModal)
4035
+ pushBtn.removeEventListener('click', () => window.location.href = '/github')
4036
+ pushBtn.addEventListener('click', showPublishModal)
4037
+ }
4038
+ } catch (error) {
4039
+ console.error('Error checking remotes:', error)
4040
+ // Default to "Login" on error
4041
+ pushBtn.innerHTML = '<span><i class="fa-brands fa-github"></i> Login</span>'
4042
+ pushBtn.removeEventListener('click', showPublishModal)
4043
+ pushBtn.removeEventListener('click', showCreateModal)
4044
+ pushBtn.addEventListener('click', () => {
4045
+ window.location.href = '/github'
4046
+ })
4047
+ }
4048
+ }
4049
+
3831
4050
  // Add click handlers for the buttons
3832
4051
  document.querySelector('#fs-changes-btn').addEventListener('click', () => showGitDiffModal())
3833
4052
  document.querySelector('#fs-history-btn').addEventListener('click', showGitHistoryModal)
3834
4053
 
4054
+ // Initialize the publish/create button
4055
+ updatePublishButton()
4056
+
3835
4057
  check_git()
3836
4058
  setInterval(check_git, 10000)
3837
4059
  <% } %>