Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: enabling git in start project dialog in desktop and ui icon/ux changes in browser app #2046

Merged
merged 3 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/assets/new-project/assets/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,12 @@ img {
margin-bottom: 30px;
}

.project-bottom {
border-top: 3px solid rgba(255, 255, 255, 0.1);
padding-top: 20px;
margin-top: auto;
}

.new-project-content {
overflow-y: auto;
}
Expand Down
4 changes: 0 additions & 4 deletions src/assets/new-project/assets/js/code-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,6 @@ function initCodeEditor() {
_openURLInTauri(document.getElementById(iconID).getAttribute('href'));
};
}
if(window.top.__TAURI__) {
// in desktop, we don't show github project option till we have git extension integrated.
document.getElementById("newGitHubProject").classList.add("forced-hidden");
}
document.getElementById("newGitHubProject").onclick = function() {
Metrics.countEvent(Metrics.EVENT_TYPE.NEW_PROJECT, "main.Click", "github-project");
window.location.href = 'new-project-github.html';
Expand Down
118 changes: 118 additions & 0 deletions src/assets/new-project/assets/js/new-git-project.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* GNU AGPL-3.0 License
*
* Copyright (c) 2021 - present core.ai . All rights reserved.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
* for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
*
*/

/*global newProjectExtension, Strings, Metrics*/
/*eslint no-console: 0*/
/*eslint strict: ["error", "global"]*/
/* jshint ignore:start */

function desktopInit() {
const LAST_GIT_CLONE_BASE_DIR = "PH_LAST_GIT_CLONE_BASE_DIR";
let createProjectBtn, websiteURLInput, locationInput;

function _validateGitURL(errors) {
let gitURL = websiteURLInput.value;
if(gitURL){
$(websiteURLInput).removeClass("error-border");
return true;
}
$(websiteURLInput).addClass("error-border");
errors.push(`<span><i class="fas fa-exclamation-triangle" style="color: #f89406"></i>&nbsp;&nbsp;${Strings.ERROR_GIT_URL_INVALID}</span>`);
return false;
}

function _validateProjectLocation(errors) {
let location = locationInput.value;
if( location === Strings.PLEASE_SELECT_A_FOLDER){
$(locationInput).addClass("error-border");
return false;
}
if(locationInput.error){
errors.push(`<span><i class="fas fa-exclamation-triangle" style="color: #f89406"></i>&nbsp;&nbsp;${locationInput.error}</span>`);
$(locationInput).addClass("error-border");
return false;
}
$(locationInput).removeClass("error-border");
return true;
}

function _validate() {
const errors = [];
let isValid = _validateGitURL(errors);
isValid = _validateProjectLocation(errors) && isValid;
$(createProjectBtn).prop('disabled', !isValid);
const $messageDisplay = $("#messageDisplay");
$messageDisplay.html("");
if(!isValid) {
$messageDisplay.html(errors.join("<br>"));
}
return isValid;
}

async function _deduceClonePath(newPath) {
if(!newPath){
newPath = locationInput.originalPath;
}
if(!newPath){
return;
}
const {clonePath, error} = await newProjectExtension.getGitCloneDir(newPath, websiteURLInput.value);
locationInput.clonePath = clonePath;
locationInput.value = window.top.Phoenix.fs.getTauriPlatformPath(clonePath);
locationInput.error = error;
locationInput.originalPath = newPath;
}

function _selectFolder() {
newProjectExtension.showFolderSelect(locationInput.originalPath || "")
.then((newPath)=>{
_deduceClonePath(newPath).then(_validate);
}).catch((err)=>{
console.error("user cancelled or error", err);
});
}

function _createProjectClicked() {
localStorage.setItem(LAST_GIT_CLONE_BASE_DIR, locationInput.originalPath);
newProjectExtension.gitClone(websiteURLInput.value, locationInput.clonePath);
Metrics.countEvent(Metrics.EVENT_TYPE.NEW_PROJECT, "git.Click", "create");
newProjectExtension.closeDialogue();
}

function initGitProject() {
$(".label-clone").text(Strings.GIT_CLONE_URL);
createProjectBtn = document.getElementById("createProjectBtn");
websiteURLInput = document.getElementById("websiteURLInput");
locationInput = document.getElementById("locationInput");
createProjectBtn.onclick = _createProjectClicked;
$(websiteURLInput).keyup(()=>{
_deduceClonePath().then(_validate);
});
locationInput.value = Strings.PLEASE_SELECT_A_FOLDER;
locationInput.onclick = _selectFolder;
websiteURLInput.value = "https://github.com/phcode-dev/HTML-Starter-Templates.git";
_deduceClonePath(localStorage.getItem(LAST_GIT_CLONE_BASE_DIR)).then(_validate);
}
window.initGitProject = initGitProject;
}

if(window.top.Phoenix.isNativeApp){
desktopInit();
}
202 changes: 107 additions & 95 deletions src/assets/new-project/assets/js/new-github-project.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,115 +23,127 @@
/*eslint strict: ["error", "global"]*/
/* jshint ignore:start */

let createProjectBtn, websiteURLInput, locationInput;
const FLATTEN_ZIP_FIRST_LEVEL_DIR = true;
function browserInit() {
let createProjectBtn, websiteURLInput, locationInput;
const FLATTEN_ZIP_FIRST_LEVEL_DIR = true;

function _isValidGitHubURL(url) {
// strip trailing slash
url = url.replace(/\/$/, "");
let githubPrefix = "https://github.com/";
let components = url.replace("https://github.com/", '').split('/');
if(!url.startsWith(githubPrefix) || components.length !== 2){
return false;
function _isValidGitHubURL(url) {
// strip trailing slash
url = url.replace(/\/$/, "");
let githubPrefix = "https://github.com/";
let components = url.replace("https://github.com/", '').split('/');
if(!url.startsWith(githubPrefix) || components.length !== 2){
return false;
}
return true;
}
return true;
}

function _fixGitHubBrokenURL() {
let githubPrefix = "https://github.com/",
gitSuffix = '.git';
let githubURL = websiteURLInput.value;
if(githubURL.startsWith("http:")){
githubURL = githubURL.replace("http:", "https:");
}
if(!githubURL.startsWith(githubPrefix)){
return;
}
// strip any query string params if present
let queryParamTrimIndex = githubURL.indexOf('?') >= 0 ? githubURL.indexOf('?') : githubURL.length;
githubURL = githubURL.substring(0, queryParamTrimIndex);
// trim everything after https://github.com/orgname/repo/... to https://github.com/orgname/repo
let components = githubURL.replace("https://github.com/", '').split('/');
// trim .git at the end of the name
if(githubURL.endsWith(gitSuffix)){
githubURL = githubURL.replace(new RegExp(gitSuffix + '$'), '');
}
if(components.length > 2){
githubURL = `https://github.com/${components[0]}/${components[1]}`;
function _fixGitHubBrokenURL() {
let githubPrefix = "https://github.com/",
gitSuffix = '.git';
let githubURL = websiteURLInput.value;
if(githubURL.startsWith("http:")){
githubURL = githubURL.replace("http:", "https:");
}
if(!githubURL.startsWith(githubPrefix)){
return;
}
// strip any query string params if present
let queryParamTrimIndex = githubURL.indexOf('?') >= 0 ? githubURL.indexOf('?') : githubURL.length;
githubURL = githubURL.substring(0, queryParamTrimIndex);
// trim everything after https://github.com/orgname/repo/... to https://github.com/orgname/repo
let components = githubURL.replace("https://github.com/", '').split('/');
// trim .git at the end of the name
if(githubURL.endsWith(gitSuffix)){
githubURL = githubURL.replace(new RegExp(gitSuffix + '$'), '');
}
if(components.length > 2){
githubURL = `https://github.com/${components[0]}/${components[1]}`;
}
websiteURLInput.value = githubURL;
}
websiteURLInput.value = githubURL;
}

function _validateGitHubURL() {
_fixGitHubBrokenURL();
let githubURL = websiteURLInput.value;
if(_isValidGitHubURL(githubURL)){
$(websiteURLInput).removeClass("error-border");
return true;
function _validateGitHubURL() {
_fixGitHubBrokenURL();
let githubURL = websiteURLInput.value;
const $messageDisplay = $("#messageDisplay");
if(_isValidGitHubURL(githubURL)){
$(websiteURLInput).removeClass("error-border");
$messageDisplay.html("");
return true;
}
$(websiteURLInput).addClass("error-border");
$messageDisplay.html(`<span><i class="fas fa-exclamation-triangle" style="color: #f89406"></i>&nbsp;&nbsp;${Strings.ERROR_ONLY_GITHUB}</span>`);
return false;
}
$(websiteURLInput).addClass("error-border");
return false;
}

function _validateProjectLocation() {
if(!window.showDirectoryPicker){
// fs access apis not present, so we will give phoenix empty location to figure out a suitable location
function _validateProjectLocation() {
if(!window.showDirectoryPicker){
// fs access apis not present, so we will give phoenix empty location to figure out a suitable location
return true;
}
let location = locationInput.value;
if( location === Strings.PLEASE_SELECT_A_FOLDER){
$(locationInput).addClass("error-border");
return false;
}
$(locationInput).removeClass("error-border");
return true;
}
let location = locationInput.value;
if( location === Strings.PLEASE_SELECT_A_FOLDER){
$(locationInput).addClass("error-border");
return false;

function _validate() {
return _validateGitHubURL()
&& _validateProjectLocation();
}
$(locationInput).removeClass("error-border");
return true;
}

function _validate() {
return _validateGitHubURL()
&& _validateProjectLocation();
}
function _selectFolder() {
newProjectExtension.showFolderSelect()
.then(file =>{
locationInput.fullPath = file;
locationInput.value = file.replace(newProjectExtension.getMountDir(), "");
_validateProjectLocation();
});
}

function _selectFolder() {
newProjectExtension.showFolderSelect()
.then(file =>{
locationInput.fullPath = file;
locationInput.value = file.replace(newProjectExtension.getMountDir(), "");
_validateProjectLocation();
});
}
function _createProjectClicked() {
if(_validate()){
let githubURL = websiteURLInput.value;
let components = githubURL.replace("https://github.com/", '').split('/');
let zipURL = `https://phcode.site/getGitHubZip?org=${components[0]}&repo=${components[1]}`;
let suggestedProjectName = `${components[0]}-${components[1]}`;
newProjectExtension.downloadAndOpenProject(
zipURL,
locationInput.fullPath, suggestedProjectName, FLATTEN_ZIP_FIRST_LEVEL_DIR)
.then(()=>{
Metrics.countEvent(Metrics.EVENT_TYPE.NEW_PROJECT, "github.Click", "create.success");
newProjectExtension.closeDialogue();
});
} else {
newProjectExtension.showErrorDialogue(
Strings.MISSING_FIELDS,
Strings.PLEASE_FILL_ALL_REQUIRED);
}
Metrics.countEvent(Metrics.EVENT_TYPE.NEW_PROJECT, "github.Click", "create");
}

function _createProjectClicked() {
if(_validate()){
let githubURL = websiteURLInput.value;
let components = githubURL.replace("https://github.com/", '').split('/');
let zipURL = `https://phcode.site/getGitHubZip?org=${components[0]}&repo=${components[1]}`;
let suggestedProjectName = `${components[0]}-${components[1]}`;
newProjectExtension.downloadAndOpenProject(
zipURL,
locationInput.fullPath, suggestedProjectName, FLATTEN_ZIP_FIRST_LEVEL_DIR)
.then(()=>{
Metrics.countEvent(Metrics.EVENT_TYPE.NEW_PROJECT, "github.Click", "create.success");
newProjectExtension.closeDialogue();
});
} else {
newProjectExtension.showErrorDialogue(
Strings.MISSING_FIELDS,
Strings.PLEASE_FILL_ALL_REQUIRED);
function initGitProject() {
if(!window.showDirectoryPicker){ // fs access apis not present
$(document.getElementById("projectLocation")).addClass("forced-hidden");
}
$(".label-clone").text(Strings.GIT_REPO_URL);
createProjectBtn = document.getElementById("createProjectBtn");
websiteURLInput = document.getElementById("websiteURLInput");
locationInput = document.getElementById("locationInput");
createProjectBtn.onclick = _createProjectClicked;
$(websiteURLInput).keyup(_validate);
locationInput.value = Strings.PLEASE_SELECT_A_FOLDER;
locationInput.onclick = _selectFolder;
websiteURLInput.value = "https://github.com/phcode-dev/HTML-Starter-Templates";
_validate();
}
Metrics.countEvent(Metrics.EVENT_TYPE.NEW_PROJECT, "github.Click", "create");
window.initGitProject = initGitProject;
}

function initGithubProject() {
if(!window.showDirectoryPicker){ // fs access apis not present
$(document.getElementById("projectLocation")).addClass("forced-hidden");
}
createProjectBtn = document.getElementById("createProjectBtn");
websiteURLInput = document.getElementById("websiteURLInput");
locationInput = document.getElementById("locationInput");
createProjectBtn.onclick = _createProjectClicked;
$(websiteURLInput).keyup(_validate);
locationInput.value = Strings.PLEASE_SELECT_A_FOLDER;
locationInput.onclick = _selectFolder;
_validate();
if(!window.top.Phoenix.isNativeApp){
browserInit();
}
4 changes: 2 additions & 2 deletions src/assets/new-project/code-editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ <h4 class="tab-title mb-0 localize">{{START_PROJECT}}</h4>
</li>
<li>
<a id="newGitHubProject" href="#" class="tabable" tabindex="5">
<img src="images/tab-img7.png" alt="image">
<span class="localize">{{GITHUB_PROJECT}}</span>
<img src="images/git.svg" alt="image">
<span class="localize">{{GIT_PROJECT}}</span>
</a>
</li>
<!-- <li>-->
Expand Down
4 changes: 4 additions & 0 deletions src/assets/new-project/images/git.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/new-project/images/tab-img7.png
Binary file not shown.
Loading
Loading