pinokiod 3.308.0 → 3.309.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.
- package/kernel/environment.js +7 -5
- package/kernel/index.js +1 -1
- package/package.json +1 -1
- package/server/index.js +41 -20
- package/server/views/app.ejs +269 -75
package/kernel/environment.js
CHANGED
|
@@ -591,7 +591,8 @@ const init = async (options, kernel) => {
|
|
|
591
591
|
!/logs
|
|
592
592
|
!/GEMINI.md
|
|
593
593
|
!/SPEC.md
|
|
594
|
-
!/app
|
|
594
|
+
!/app
|
|
595
|
+
!${kernel.homedir}`)
|
|
595
596
|
}
|
|
596
597
|
|
|
597
598
|
const gitDir = path.resolve(root, ".git")
|
|
@@ -620,13 +621,14 @@ const init = async (options, kernel) => {
|
|
|
620
621
|
"ENVIRONMENT",
|
|
621
622
|
// ".*",
|
|
622
623
|
// "~*",
|
|
623
|
-
"/.pinokio-temp
|
|
624
|
-
"/logs
|
|
625
|
-
"/cache
|
|
624
|
+
"/.pinokio-temp",
|
|
625
|
+
"/logs",
|
|
626
|
+
"/cache",
|
|
626
627
|
"/AGENTS.md",
|
|
627
628
|
"/CLAUDE.md",
|
|
628
629
|
"/GEMINI.md",
|
|
629
|
-
"/QWEN.md"
|
|
630
|
+
"/QWEN.md",
|
|
631
|
+
"/.geminiignore"
|
|
630
632
|
]
|
|
631
633
|
|
|
632
634
|
const missingEntries = entriesToEnsure.filter(entry => !existingEntries.has(entry))
|
package/kernel/index.js
CHANGED
|
@@ -1035,7 +1035,7 @@ class Kernel {
|
|
|
1035
1035
|
}
|
|
1036
1036
|
}
|
|
1037
1037
|
})
|
|
1038
|
-
if (this.bin.installed.conda.has("git")) {
|
|
1038
|
+
if (this.bin.installed && this.bin.installed.conda && this.bin.installed.conda.has("git")) {
|
|
1039
1039
|
await Promise.all([
|
|
1040
1040
|
this.proto.init(),
|
|
1041
1041
|
this.plugin.init(),
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -178,6 +178,46 @@ class Server {
|
|
|
178
178
|
process.on('unhandledRejection', (reason) => invoke(reason, 'unhandledRejection'))
|
|
179
179
|
this.fatalHandlersInstalled = true
|
|
180
180
|
}
|
|
181
|
+
|
|
182
|
+
async ensureGitconfigDefaults(home) {
|
|
183
|
+
const gitconfigPath = path.resolve(home, "gitconfig")
|
|
184
|
+
const templatePath = path.resolve(__dirname, "..", "kernel", "gitconfig_template")
|
|
185
|
+
const required = [
|
|
186
|
+
{ section: "init", key: "defaultBranch", value: "main" },
|
|
187
|
+
{ section: "push", key: "autoSetupRemote", value: true },
|
|
188
|
+
]
|
|
189
|
+
|
|
190
|
+
const exists = await this.kernel.exists(gitconfigPath)
|
|
191
|
+
if (!exists) {
|
|
192
|
+
await fs.promises.copyFile(templatePath, gitconfigPath)
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
let config
|
|
197
|
+
let dirty = false
|
|
198
|
+
try {
|
|
199
|
+
const content = await fs.promises.readFile(gitconfigPath, "utf8")
|
|
200
|
+
config = ini.parse(content)
|
|
201
|
+
} catch (e) {
|
|
202
|
+
config = {}
|
|
203
|
+
dirty = true
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
for (const { section, key, value } of required) {
|
|
207
|
+
if (!config[section]) {
|
|
208
|
+
config[section] = {}
|
|
209
|
+
}
|
|
210
|
+
const current = config[section][key]
|
|
211
|
+
if (String(current) !== String(value)) {
|
|
212
|
+
config[section][key] = value
|
|
213
|
+
dirty = true
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (dirty) {
|
|
218
|
+
await fs.promises.writeFile(gitconfigPath, ini.stringify(config))
|
|
219
|
+
}
|
|
220
|
+
}
|
|
181
221
|
async handleFatalError(error, origin) {
|
|
182
222
|
if (this.handlingFatalError) {
|
|
183
223
|
console.error(`[Pinokiod] Additional fatal (${origin})`, (error && error.stack) ? error.stack : error)
|
|
@@ -219,20 +259,6 @@ class Server {
|
|
|
219
259
|
} catch (err) {
|
|
220
260
|
console.error('Failed to emit fatal notification:', err)
|
|
221
261
|
}
|
|
222
|
-
if (!this.fatalExitTimer) {
|
|
223
|
-
this.fatalExitTimer = setTimeout(() => {
|
|
224
|
-
try {
|
|
225
|
-
this.shutdown('Fatal Error')
|
|
226
|
-
} catch (shutdownErr) {
|
|
227
|
-
console.error('Failed to shutdown after fatal error:', shutdownErr)
|
|
228
|
-
}
|
|
229
|
-
try {
|
|
230
|
-
process.exit(1)
|
|
231
|
-
} catch (_) {
|
|
232
|
-
// ignore
|
|
233
|
-
}
|
|
234
|
-
}, 500)
|
|
235
|
-
}
|
|
236
262
|
}
|
|
237
263
|
stop() {
|
|
238
264
|
this.server.close()
|
|
@@ -4155,12 +4181,7 @@ class Server {
|
|
|
4155
4181
|
let p4 = path.resolve(home, "network/system")
|
|
4156
4182
|
await fse.remove(p4)
|
|
4157
4183
|
|
|
4158
|
-
|
|
4159
|
-
await fse.remove(gitconfig)
|
|
4160
|
-
await fs.promises.copyFile(
|
|
4161
|
-
path.resolve(__dirname, "..", "kernel", "gitconfig_template"),
|
|
4162
|
-
gitconfig
|
|
4163
|
-
)
|
|
4184
|
+
await this.ensureGitconfigDefaults(home)
|
|
4164
4185
|
|
|
4165
4186
|
let prototype_path = path.resolve(home, "prototype")
|
|
4166
4187
|
await fse.remove(prototype_path)
|
package/server/views/app.ejs
CHANGED
|
@@ -2177,6 +2177,10 @@ body.dark {
|
|
|
2177
2177
|
padding-top: 12px;
|
|
2178
2178
|
}
|
|
2179
2179
|
|
|
2180
|
+
.pinokio-modal-footer--create {
|
|
2181
|
+
padding-top: 12px;
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2180
2184
|
.pinokio-modal-footer.pinokio-modal-footer--publish {
|
|
2181
2185
|
display: none;
|
|
2182
2186
|
padding-top: 12px;
|
|
@@ -2200,6 +2204,21 @@ body.dark {
|
|
|
2200
2204
|
background: rgba(127, 91, 243, 1) !important;
|
|
2201
2205
|
}
|
|
2202
2206
|
|
|
2207
|
+
.pinokio-modal-secondary-btn {
|
|
2208
|
+
padding: 10px 22px;
|
|
2209
|
+
border-radius: 999px;
|
|
2210
|
+
border: 1px solid rgba(127, 91, 243, 0.35);
|
|
2211
|
+
background: transparent;
|
|
2212
|
+
color: var(--pinokio-modal-body-text-color);
|
|
2213
|
+
font-weight: 600;
|
|
2214
|
+
cursor: pointer;
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
.pinokio-modal-secondary-btn:hover {
|
|
2218
|
+
border-color: rgba(127, 91, 243, 0.6);
|
|
2219
|
+
color: #fff;
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2203
2222
|
.pinokio-modal-body--fork {
|
|
2204
2223
|
display: flex;
|
|
2205
2224
|
flex-direction: column;
|
|
@@ -5699,6 +5718,30 @@ const rerenderMenuSection = (container, html) => {
|
|
|
5699
5718
|
return { owner: null, name: null, full: null }
|
|
5700
5719
|
}
|
|
5701
5720
|
|
|
5721
|
+
function buildRemoteWebUrl(remoteUrl) {
|
|
5722
|
+
if (!remoteUrl || typeof remoteUrl !== 'string') {
|
|
5723
|
+
return null
|
|
5724
|
+
}
|
|
5725
|
+
const trimmed = remoteUrl.trim()
|
|
5726
|
+
if (!trimmed) {
|
|
5727
|
+
return null
|
|
5728
|
+
}
|
|
5729
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
5730
|
+
return trimmed
|
|
5731
|
+
}
|
|
5732
|
+
const slug = parseRemoteSlug(trimmed)
|
|
5733
|
+
if (slug && slug.full) {
|
|
5734
|
+
return `https://github.com/${slug.full}`
|
|
5735
|
+
}
|
|
5736
|
+
if (trimmed.startsWith('git@')) {
|
|
5737
|
+
const sshSlug = parseRemoteSlug(trimmed.replace(/^git@/, '').replace(/:/, '/'))
|
|
5738
|
+
if (sshSlug && sshSlug.full) {
|
|
5739
|
+
return `https://github.com/${sshSlug.full}`
|
|
5740
|
+
}
|
|
5741
|
+
}
|
|
5742
|
+
return trimmed
|
|
5743
|
+
}
|
|
5744
|
+
|
|
5702
5745
|
function deriveForkDefaultName(repo) {
|
|
5703
5746
|
if (!repo) {
|
|
5704
5747
|
return workspaceName || 'fork'
|
|
@@ -5986,16 +6029,30 @@ const rerenderMenuSection = (container, html) => {
|
|
|
5986
6029
|
return repoData
|
|
5987
6030
|
}
|
|
5988
6031
|
|
|
6032
|
+
const getRepoChangeCount = (repo) => {
|
|
6033
|
+
if (!repo) {
|
|
6034
|
+
return 0
|
|
6035
|
+
}
|
|
6036
|
+
if (typeof repo.changeCount === 'number') {
|
|
6037
|
+
return repo.changeCount
|
|
6038
|
+
}
|
|
6039
|
+
if (Array.isArray(repo.changes)) {
|
|
6040
|
+
return repo.changes.length
|
|
6041
|
+
}
|
|
6042
|
+
return 0
|
|
6043
|
+
}
|
|
6044
|
+
|
|
5989
6045
|
async function ensureRemoteForPublish({ repoParam, repoName }) {
|
|
5990
6046
|
const label = repoName || repoParam || 'Repository'
|
|
5991
6047
|
const initialRepo = await getRepoData(repoParam)
|
|
5992
6048
|
if (hasRemoteConfigured(initialRepo)) {
|
|
5993
|
-
return true
|
|
6049
|
+
return { remoteReady: true, shouldOpenPublish: true }
|
|
5994
6050
|
}
|
|
5995
6051
|
|
|
5996
|
-
const creationResult = await showCreateModal({ skipReload: true })
|
|
5997
|
-
|
|
5998
|
-
|
|
6052
|
+
const creationResult = await showCreateModal({ skipReload: true, repoParam, repoName })
|
|
6053
|
+
const action = creationResult && creationResult.action ? creationResult.action : null
|
|
6054
|
+
if (!creationResult || creationResult.completed === false || action === 'cancel') {
|
|
6055
|
+
return { remoteReady: false, shouldOpenPublish: false }
|
|
5999
6056
|
}
|
|
6000
6057
|
|
|
6001
6058
|
if (typeof check_git === 'function') {
|
|
@@ -6003,7 +6060,7 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6003
6060
|
}
|
|
6004
6061
|
const refreshedRepo = await getRepoData(repoParam)
|
|
6005
6062
|
if (hasRemoteConfigured(refreshedRepo)) {
|
|
6006
|
-
return true
|
|
6063
|
+
return { remoteReady: true, shouldOpenPublish: true }
|
|
6007
6064
|
}
|
|
6008
6065
|
|
|
6009
6066
|
Swal.fire({
|
|
@@ -6011,7 +6068,7 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6011
6068
|
title: `${escapeHtml(label)} still needs a Git remote`,
|
|
6012
6069
|
text: 'Add a remote (for example, origin) and try publishing again.'
|
|
6013
6070
|
})
|
|
6014
|
-
return false
|
|
6071
|
+
return { remoteReady: false, shouldOpenPublish: false }
|
|
6015
6072
|
}
|
|
6016
6073
|
|
|
6017
6074
|
const buildPublishPreflightCopy = (repoName, reason) => {
|
|
@@ -6037,6 +6094,65 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6037
6094
|
}
|
|
6038
6095
|
}
|
|
6039
6096
|
|
|
6097
|
+
const promptCommitBeforePublish = async ({ repoParam, repoName }) => {
|
|
6098
|
+
const repoData = await getRepoData(repoParam)
|
|
6099
|
+
const changeCount = getRepoChangeCount(repoData)
|
|
6100
|
+
if (changeCount <= 0) {
|
|
6101
|
+
return { proceed: true, action: 'skip', changeCount }
|
|
6102
|
+
}
|
|
6103
|
+
|
|
6104
|
+
const displayName = repoName || (repoData && repoData.name) || repoParam || 'Repository'
|
|
6105
|
+
const safeName = escapeHtml(displayName)
|
|
6106
|
+
const result = await Swal.fire({
|
|
6107
|
+
html: `
|
|
6108
|
+
<div class="pinokio-modal-surface">
|
|
6109
|
+
<div class="pinokio-modal-header">
|
|
6110
|
+
<div class="pinokio-modal-icon"><i class="fa-solid fa-code-commit"></i></div>
|
|
6111
|
+
<div class="pinokio-modal-heading">
|
|
6112
|
+
<div class="pinokio-modal-title">Commit changes before publishing?</div>
|
|
6113
|
+
<div class="pinokio-modal-subtitle">${safeName} has ${changeCount} uncommitted change${changeCount === 1 ? '' : 's'}.</div>
|
|
6114
|
+
</div>
|
|
6115
|
+
</div>
|
|
6116
|
+
</div>
|
|
6117
|
+
`,
|
|
6118
|
+
customClass: {
|
|
6119
|
+
popup: 'pinokio-modern-modal',
|
|
6120
|
+
htmlContainer: 'pinokio-modern-html',
|
|
6121
|
+
confirmButton: 'pinokio-modern-confirm',
|
|
6122
|
+
cancelButton: 'pinokio-modern-cancel',
|
|
6123
|
+
closeButton: 'pinokio-modern-close'
|
|
6124
|
+
},
|
|
6125
|
+
backdrop: 'rgba(9,11,15,0.65)',
|
|
6126
|
+
width: 'min(520px, 92vw)',
|
|
6127
|
+
showCloseButton: true,
|
|
6128
|
+
showCancelButton: true,
|
|
6129
|
+
showConfirmButton: true,
|
|
6130
|
+
buttonsStyling: false,
|
|
6131
|
+
allowOutsideClick: false,
|
|
6132
|
+
allowEscapeKey: false,
|
|
6133
|
+
reverseButtons: true,
|
|
6134
|
+
confirmButtonText: 'Review & Commit',
|
|
6135
|
+
cancelButtonText: 'Continue without committing',
|
|
6136
|
+
focusConfirm: false
|
|
6137
|
+
})
|
|
6138
|
+
|
|
6139
|
+
if (result.isConfirmed) {
|
|
6140
|
+
try {
|
|
6141
|
+
await showGitDiffModal({ repoParam, repoName: displayName, forceRefresh: true })
|
|
6142
|
+
} catch (error) {
|
|
6143
|
+
console.error('Failed to open commit modal before publish:', error)
|
|
6144
|
+
}
|
|
6145
|
+
if (typeof check_git === 'function') {
|
|
6146
|
+
await check_git()
|
|
6147
|
+
}
|
|
6148
|
+
return { proceed: true, action: 'commit', changeCount }
|
|
6149
|
+
}
|
|
6150
|
+
if (result.dismiss === Swal.DismissReason.cancel) {
|
|
6151
|
+
return { proceed: true, action: 'skip', changeCount }
|
|
6152
|
+
}
|
|
6153
|
+
return { proceed: false, action: 'dismiss', changeCount }
|
|
6154
|
+
}
|
|
6155
|
+
|
|
6040
6156
|
const showPublishPreflightModal = ({ title, message, actionLabel, onAction }) => {
|
|
6041
6157
|
const safeTitle = escapeHtml(title || 'Repository is not ready to publish')
|
|
6042
6158
|
const safeMessage = escapeHtml(message || 'Resolve the issue and try again.')
|
|
@@ -6081,6 +6197,59 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6081
6197
|
})
|
|
6082
6198
|
}
|
|
6083
6199
|
|
|
6200
|
+
const handlePreflightFailure = ({ preflight, repoParam, repoName }) => {
|
|
6201
|
+
if (!preflight) {
|
|
6202
|
+
return
|
|
6203
|
+
}
|
|
6204
|
+
if (preflight.reason === 'network') {
|
|
6205
|
+
Swal.fire({
|
|
6206
|
+
icon: 'error',
|
|
6207
|
+
title: 'Unable to check repository state',
|
|
6208
|
+
text: 'Please try again in a moment.'
|
|
6209
|
+
})
|
|
6210
|
+
return
|
|
6211
|
+
}
|
|
6212
|
+
const copy = buildPublishPreflightCopy(repoName, preflight.reason)
|
|
6213
|
+
showPublishPreflightModal({
|
|
6214
|
+
title: copy.title,
|
|
6215
|
+
message: copy.message,
|
|
6216
|
+
actionLabel: copy.actionLabel,
|
|
6217
|
+
onAction: () => launchPublishPreflightDiffFlow({ repoParam, repoName })
|
|
6218
|
+
})
|
|
6219
|
+
}
|
|
6220
|
+
|
|
6221
|
+
const runPublishFlow = async ({ repoParam, repoName }) => {
|
|
6222
|
+
let preflight = await fetchPublishPreflightState(repoParam)
|
|
6223
|
+
if (!preflight.ok) {
|
|
6224
|
+
handlePreflightFailure({ preflight, repoParam, repoName })
|
|
6225
|
+
return
|
|
6226
|
+
}
|
|
6227
|
+
|
|
6228
|
+
const commitDecision = await promptCommitBeforePublish({ repoParam, repoName })
|
|
6229
|
+
if (!commitDecision || commitDecision.proceed !== true) {
|
|
6230
|
+
return
|
|
6231
|
+
}
|
|
6232
|
+
|
|
6233
|
+
if (commitDecision.action === 'commit') {
|
|
6234
|
+
preflight = await fetchPublishPreflightState(repoParam)
|
|
6235
|
+
if (!preflight.ok) {
|
|
6236
|
+
handlePreflightFailure({ preflight, repoParam, repoName })
|
|
6237
|
+
return
|
|
6238
|
+
}
|
|
6239
|
+
}
|
|
6240
|
+
|
|
6241
|
+
const remoteOutcome = await ensureRemoteForPublish({ repoParam, repoName })
|
|
6242
|
+
const remoteReady = typeof remoteOutcome === 'object'
|
|
6243
|
+
? remoteOutcome.remoteReady
|
|
6244
|
+
: Boolean(remoteOutcome)
|
|
6245
|
+
const shouldOpenPublish = typeof remoteOutcome === 'object'
|
|
6246
|
+
? remoteOutcome.shouldOpenPublish !== false
|
|
6247
|
+
: remoteReady
|
|
6248
|
+
if (remoteReady && shouldOpenPublish) {
|
|
6249
|
+
showPublishModal({ repoParam, repoName })
|
|
6250
|
+
}
|
|
6251
|
+
}
|
|
6252
|
+
|
|
6084
6253
|
const launchPublishPreflightDiffFlow = async ({ repoParam, repoName }) => {
|
|
6085
6254
|
try {
|
|
6086
6255
|
await showGitDiffModal({ repoParam, repoName, forceRefresh: true })
|
|
@@ -6092,10 +6261,7 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6092
6261
|
const retryState = await fetchPublishPreflightState(repoParam)
|
|
6093
6262
|
if (retryState.ok) {
|
|
6094
6263
|
closeStatusDropdowns()
|
|
6095
|
-
|
|
6096
|
-
if (remoteReady) {
|
|
6097
|
-
showPublishModal({ repoParam, repoName })
|
|
6098
|
-
}
|
|
6264
|
+
await runPublishFlow({ repoParam, repoName })
|
|
6099
6265
|
}
|
|
6100
6266
|
} catch (error) {
|
|
6101
6267
|
console.error('Failed to retry publish after diff:', error)
|
|
@@ -6104,29 +6270,7 @@ const rerenderMenuSection = (container, html) => {
|
|
|
6104
6270
|
|
|
6105
6271
|
const handlePublishDropdownClick = async ({ repoParam, repoName }) => {
|
|
6106
6272
|
closeStatusDropdowns()
|
|
6107
|
-
|
|
6108
|
-
if (preflight.ok) {
|
|
6109
|
-
const remoteReady = await ensureRemoteForPublish({ repoParam, repoName })
|
|
6110
|
-
if (remoteReady) {
|
|
6111
|
-
showPublishModal({ repoParam, repoName })
|
|
6112
|
-
}
|
|
6113
|
-
return
|
|
6114
|
-
}
|
|
6115
|
-
if (preflight.reason === 'network') {
|
|
6116
|
-
Swal.fire({
|
|
6117
|
-
icon: 'error',
|
|
6118
|
-
title: 'Unable to check repository state',
|
|
6119
|
-
text: 'Please try again in a moment.'
|
|
6120
|
-
})
|
|
6121
|
-
return
|
|
6122
|
-
}
|
|
6123
|
-
const copy = buildPublishPreflightCopy(repoName, preflight.reason)
|
|
6124
|
-
showPublishPreflightModal({
|
|
6125
|
-
title: copy.title,
|
|
6126
|
-
message: copy.message,
|
|
6127
|
-
actionLabel: copy.actionLabel,
|
|
6128
|
-
onAction: () => launchPublishPreflightDiffFlow({ repoParam, repoName })
|
|
6129
|
-
})
|
|
6273
|
+
await runPublishFlow({ repoParam, repoName })
|
|
6130
6274
|
}
|
|
6131
6275
|
|
|
6132
6276
|
const renderPublishDropdown = (repos, options = {}) => {
|
|
@@ -7302,10 +7446,28 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7302
7446
|
const iframe = popup.querySelector('iframe')
|
|
7303
7447
|
const footer = popup.querySelector('[data-publish-footer]')
|
|
7304
7448
|
const closeBtn = popup.querySelector('[data-publish-close]')
|
|
7449
|
+
const viewBtn = popup.querySelector('[data-publish-view-remote]')
|
|
7450
|
+
const remoteHref = viewBtn ? viewBtn.getAttribute('data-remote-url') : null
|
|
7305
7451
|
|
|
7306
7452
|
if (closeBtn) {
|
|
7307
7453
|
closeBtn.addEventListener('click', () => Swal.close())
|
|
7308
7454
|
}
|
|
7455
|
+
if (viewBtn) {
|
|
7456
|
+
if (remoteHref) {
|
|
7457
|
+
viewBtn.addEventListener('click', (event) => {
|
|
7458
|
+
event.preventDefault()
|
|
7459
|
+
event.stopPropagation()
|
|
7460
|
+
try {
|
|
7461
|
+
window.open(remoteHref, '_blank', 'browser')
|
|
7462
|
+
} catch (error) {
|
|
7463
|
+
console.error('Failed to open remote URL:', error)
|
|
7464
|
+
}
|
|
7465
|
+
})
|
|
7466
|
+
} else {
|
|
7467
|
+
viewBtn.disabled = true
|
|
7468
|
+
viewBtn.setAttribute('title', 'Remote URL not available')
|
|
7469
|
+
}
|
|
7470
|
+
}
|
|
7309
7471
|
|
|
7310
7472
|
if (iframe) {
|
|
7311
7473
|
iframe.dataset.forceVisible = 'true'
|
|
@@ -7388,12 +7550,17 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7388
7550
|
return
|
|
7389
7551
|
}
|
|
7390
7552
|
|
|
7391
|
-
const
|
|
7553
|
+
const remoteUrl = repoData && typeof repoData.url === 'string' ? repoData.url.trim() : ''
|
|
7554
|
+
const remoteWebUrl = buildRemoteWebUrl(remoteUrl)
|
|
7555
|
+
const remoteDisplay = remoteUrl ? escapeHtml(remoteUrl) : null
|
|
7392
7556
|
const subtitle = `${escapeHtml(repoLabel)} — review your latest changes before publishing.`
|
|
7393
7557
|
const remoteHtml = remoteDisplay ? `<div class="pinokio-fork-item-url">${remoteDisplay}</div>` : ''
|
|
7394
7558
|
const timestampedUri = pushUri.includes('?')
|
|
7395
7559
|
? `${pushUri}&ts=${Date.now()}`
|
|
7396
7560
|
: `${pushUri}?ts=${Date.now()}`
|
|
7561
|
+
const viewRemoteButton = remoteWebUrl
|
|
7562
|
+
? `<button type="button" class="pinokio-modal-secondary-btn" data-publish-view-remote data-remote-url="${escapeHtml(remoteWebUrl)}">View on GitHub</button>`
|
|
7563
|
+
: ''
|
|
7397
7564
|
|
|
7398
7565
|
const modalHtml = `
|
|
7399
7566
|
<div class="pinokio-modal-surface">
|
|
@@ -7409,6 +7576,7 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7409
7576
|
<iframe src="${timestampedUri}"></iframe>
|
|
7410
7577
|
</div>
|
|
7411
7578
|
<div class="pinokio-modal-footer pinokio-modal-footer--publish" data-publish-footer>
|
|
7579
|
+
${viewRemoteButton}
|
|
7412
7580
|
<button type="button" class="pinokio-publish-close-btn" data-publish-close>Close</button>
|
|
7413
7581
|
</div>
|
|
7414
7582
|
</div>
|
|
@@ -7598,11 +7766,13 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7598
7766
|
backdrop: 'rgba(9,11,15,0.65)',
|
|
7599
7767
|
width: 'min(520px, 90vw)',
|
|
7600
7768
|
buttonsStyling: false,
|
|
7601
|
-
showCloseButton:
|
|
7769
|
+
showCloseButton: false,
|
|
7602
7770
|
showConfirmButton: true,
|
|
7603
7771
|
showCancelButton: true,
|
|
7604
7772
|
confirmButtonText: 'Create on GitHub',
|
|
7605
7773
|
cancelButtonText: 'Cancel',
|
|
7774
|
+
allowOutsideClick: false,
|
|
7775
|
+
allowEscapeKey: false,
|
|
7606
7776
|
focusConfirm: false,
|
|
7607
7777
|
preConfirm: () => {
|
|
7608
7778
|
const repoName = document.getElementById('create-repo-name-input').value.trim()
|
|
@@ -7623,21 +7793,14 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7623
7793
|
|
|
7624
7794
|
return createRepoModalPromise.then((result) => {
|
|
7625
7795
|
if (!result || !result.isConfirmed) {
|
|
7626
|
-
return { completed: false, result }
|
|
7796
|
+
return { completed: false, action: 'cancel', result }
|
|
7627
7797
|
}
|
|
7628
7798
|
const { name, isPrivate } = result.value
|
|
7629
|
-
return showCreateRepoIframeModal(name, isPrivate, opts)
|
|
7630
|
-
if (iframeResult && iframeResult.completed === false) {
|
|
7631
|
-
return { completed: false, result: iframeResult }
|
|
7632
|
-
}
|
|
7633
|
-
return { completed: true, result: iframeResult }
|
|
7634
|
-
})
|
|
7799
|
+
return showCreateRepoIframeModal(name, isPrivate, opts)
|
|
7635
7800
|
})
|
|
7636
7801
|
}
|
|
7637
7802
|
|
|
7638
7803
|
const showCreateRepoIframeModal = (name, isPrivate, options = {}) => {
|
|
7639
|
-
const opts = typeof options === 'object' && options !== null ? options : {}
|
|
7640
|
-
const skipReload = Boolean(opts.skipReload)
|
|
7641
7804
|
const createUri = document.querySelector('#fs-status').getAttribute('data-create-uri')
|
|
7642
7805
|
|
|
7643
7806
|
if (!createUri) {
|
|
@@ -7654,40 +7817,71 @@ const rerenderMenuSection = (container, html) => {
|
|
|
7654
7817
|
urlParams.append('visibility', isPrivate ? 'private' : 'public')
|
|
7655
7818
|
|
|
7656
7819
|
const finalUri = `${createUri}${createUri.includes('?') ? '&' : '?'}${urlParams.toString()}`
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7820
|
+
|
|
7821
|
+
return new Promise((resolve) => {
|
|
7822
|
+
let resolved = false
|
|
7823
|
+
const finalize = (payload) => {
|
|
7824
|
+
if (resolved) {
|
|
7825
|
+
return
|
|
7826
|
+
}
|
|
7827
|
+
resolved = true
|
|
7828
|
+
resolve(payload)
|
|
7829
|
+
}
|
|
7830
|
+
|
|
7831
|
+
Swal.fire({
|
|
7832
|
+
html: `
|
|
7833
|
+
<div class="pinokio-modal-surface">
|
|
7834
|
+
<div class="pinokio-modal-header">
|
|
7835
|
+
<div class="pinokio-modal-icon"><i class="fa-brands fa-github"></i></div>
|
|
7836
|
+
<div class="pinokio-modal-heading">
|
|
7837
|
+
<div class="pinokio-modal-title">Create GitHub repository</div>
|
|
7838
|
+
<div class="pinokio-modal-subtitle">${name} · ${isPrivate ? 'Private' : 'Public'}</div>
|
|
7839
|
+
</div>
|
|
7840
|
+
</div>
|
|
7841
|
+
<div class="pinokio-modal-body pinokio-modal-body--iframe">
|
|
7842
|
+
<iframe src="${finalUri}"></iframe>
|
|
7843
|
+
</div>
|
|
7844
|
+
<div class="pinokio-modal-footer pinokio-modal-footer--create">
|
|
7845
|
+
<button type="button" class="pinokio-modal-secondary-btn" data-create-cancel>Cancel</button>
|
|
7846
|
+
<button type="button" class="pinokio-publish-close-btn" data-create-next>Next</button>
|
|
7666
7847
|
</div>
|
|
7667
7848
|
</div>
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7849
|
+
`,
|
|
7850
|
+
customClass: {
|
|
7851
|
+
popup: 'pinokio-modern-modal',
|
|
7852
|
+
htmlContainer: 'pinokio-modern-html',
|
|
7853
|
+
closeButton: 'pinokio-modern-close'
|
|
7854
|
+
},
|
|
7855
|
+
backdrop: 'rgba(9,11,15,0.65)',
|
|
7856
|
+
width: 'min(760px, 90vw)',
|
|
7857
|
+
showConfirmButton: false,
|
|
7858
|
+
showCancelButton: false,
|
|
7859
|
+
showCloseButton: false,
|
|
7860
|
+
buttonsStyling: false,
|
|
7861
|
+
allowOutsideClick: false,
|
|
7862
|
+
allowEscapeKey: false,
|
|
7863
|
+
focusConfirm: false,
|
|
7864
|
+
didOpen: (popup) => {
|
|
7865
|
+
const nextBtn = popup.querySelector('[data-create-next]')
|
|
7866
|
+
const cancelBtn = popup.querySelector('[data-create-cancel]')
|
|
7867
|
+
if (nextBtn) {
|
|
7868
|
+
nextBtn.addEventListener('click', () => {
|
|
7869
|
+
finalize({ completed: true, action: 'next', name, isPrivate })
|
|
7870
|
+
Swal.close()
|
|
7871
|
+
})
|
|
7872
|
+
}
|
|
7873
|
+
if (cancelBtn) {
|
|
7874
|
+
cancelBtn.addEventListener('click', () => {
|
|
7875
|
+
finalize({ completed: false, action: 'cancel', name, isPrivate })
|
|
7876
|
+
Swal.close()
|
|
7877
|
+
})
|
|
7878
|
+
}
|
|
7879
|
+
},
|
|
7880
|
+
willClose: () => {
|
|
7881
|
+
finalize({ completed: false, action: 'dismissed', name, isPrivate })
|
|
7882
|
+
}
|
|
7883
|
+
}).then(() => {})
|
|
7684
7884
|
})
|
|
7685
|
-
|
|
7686
|
-
if (!skipReload) {
|
|
7687
|
-
reloadOnModalClose(createRepoIframePromise)
|
|
7688
|
-
}
|
|
7689
|
-
|
|
7690
|
-
return createRepoIframePromise
|
|
7691
7885
|
}
|
|
7692
7886
|
|
|
7693
7887
|
async function showForkModalForRepo(repoParam) {
|