diff --git a/CHANGELOG.md b/CHANGELOG.md index be6d2c1..8b129b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# Version 0.25.0 + +Introducing new Markdown Editor 🎉 +available for now only as an option in settings, still not complete, but will become the default option in the future +Built with tiptap editor and tiptap-markdown extension from https://github.com/aguingand/tiptap-markdown + + +Multiple fixes +better packaging for the whole client + # Version 0.24.0 - 0.24.1 Option to create note as folder (beta for dev) diff --git a/README.md b/README.md index fd51643..a77f1a2 100755 --- a/README.md +++ b/README.md @@ -11,3 +11,45 @@ What is Carnet ? You can help with translations on the dedicated platform [weblate](https://weblate.lostpod.me) + + +## Development + +Carnet For Nextcloud is divided into two parts: + +- The server part (this repo) +- And the client part [here](../CarnetWebClient) + + +### Prepare your environment + +To start developping Carnet, you will need a working Nextcloud install + +Then, from your favorite dev folder: + +Create a carnet folder where all the dev for server and clients will happen: + +``` +mkdir carnet +cd carnet +``` + +Follow instructions on building [CarnetWebClient](../CarnetWebClient) + +Link it to templates inside the nextcloud app + +``` +git clone https://github.com/CarnetApp/CarnetNextcloud +current=`pwd` +cd CarnetNextcloud +ln -s "$current"/CarnetWebClient/dist templates/CarnetWebClient +``` +This should create a link called CarnetWebClient to the dist folder of CarnetWebClient, inside templates + +Then create a link to your nextcloud installation (replace nextcloud-install-folder with appropriate path) + +``` +ln -s "$current"/CarnetNextcloud nextcloud-install-folder/apps/carnet +``` + +Then activate is within nextcloud interface ! \ No newline at end of file diff --git a/appinfo/info.xml b/appinfo/info.xml index ec8abef..87b3420 100755 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -19,7 +19,7 @@ Mac, with sync capabilities - Statistics : words/sentences/characters - Sync with ownCloud/NextCloud - Online editor as a ownCloud/NextCloud App]]> - 0.24.7 + 0.25.0 agpl Phie Carnet @@ -33,7 +33,7 @@ Mac, with sync capabilities - + diff --git a/appinfo/routes.php b/appinfo/routes.php index f42e891..6706e2d 100755 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -57,8 +57,8 @@ ['name' => 'note#deleteNote', 'url' => '/notes', 'verb' => 'DELETE'], ['name' => 'note#search', 'url' => '/notes/search', 'verb' => 'GET'], ['name' => 'note#getSearchCache', 'url' => '/notes/getSearchCache', 'verb' => 'GET'], - ['name' => 'note#getUbuntuFont', 'url' => '/templates/CarnetElectron/fonts/ubuntu.woff2', 'verb' => 'GET' ], - ['name' => 'note#getMaterialFont', 'url' => '/templates/CarnetElectron/fonts/material-icons.woff2', 'verb' => 'GET' ], + ['name' => 'note#getUbuntuFont', 'url' => '/templates/CarnetWebClient/fonts/ubuntu.woff2', 'verb' => 'GET' ], + ['name' => 'note#getMaterialFont', 'url' => '/templates/CarnetWebClient/fonts/material-icons.woff2', 'verb' => 'GET' ], ['name' => 'note#getChangelog', 'url' => '/settings/changelog', 'verb' => 'GET' ], ['name' => 'note#getLangJson', 'url' => '/settings/lang/json', 'verb' => 'GET' ], ['name' => 'note#getUISettings', 'url' => '/settings/ui', 'verb' => 'GET' ], @@ -76,7 +76,8 @@ ['name' => 'note#setShouldUseFolderNotes', 'url' => '/settings/note_folder', 'verb' => 'POST' ], ['name' => 'note#shouldUseFolderNotes', 'url' => '/settings/note_folder', 'verb' => 'GET' ], - + ['name' => 'note#useMDEditor', 'url' => '/settings/use_md_editor', 'verb' => 'GET' ], + ['name' => 'note#setUseMDEditor', 'url' => '/settings/use_md_editor', 'verb' => 'POST' ] ] ]; \ No newline at end of file diff --git a/lib/Controller/NoteController.php b/lib/Controller/NoteController.php index 5b3c34f..7b100e3 100755 --- a/lib/Controller/NoteController.php +++ b/lib/Controller/NoteController.php @@ -280,7 +280,7 @@ private function getKeywordsDBFile(){ */ public function getLangJson($lang){ if($lang !== ".." && $lang !== "../"){ - $response = new StreamResponse(__DIR__.'/../../templates/CarnetElectron/i18n/'.$lang.".json"); + $response = new StreamResponse(__DIR__.'/../../templates/CarnetWebClient/i18n/'.$lang.".json"); $response->addHeader("Content-Type", "application/json"); $response->cacheFor(604800); return $response; @@ -296,7 +296,7 @@ public function getLangJson($lang){ * @NoCSRFRequired */ public function getOpusDecoderJavascript(){ - $response = new StreamResponse(__DIR__.'/../../templates/CarnetElectron/reader/libs/recorder/decoderWorker.min.js'); + $response = new StreamResponse(__DIR__.'/../../templates/CarnetWebClient/reader/libs/recorder/decoderWorker.min.js'); $response->addHeader("Content-Type", "application/javascript"); return $response; } @@ -307,7 +307,7 @@ public function getOpusDecoderJavascript(){ * @NoCSRFRequired */ public function getOpusEncoderJavascript(){ - $response = new StreamResponse(__DIR__.'/../../templates/CarnetElectron/reader/libs/recorder/encoderWorker.min.js'); + $response = new StreamResponse(__DIR__.'/../../templates/CarnetWebClient/reader/libs/recorder/encoderWorker.min.js'); $response->addHeader("Content-Type", "application/javascript"); return $response; } @@ -320,7 +320,7 @@ public function getOpusEncoderJavascript(){ public function getOpusEncoder(){ echo"bla"; return; - $response = new StreamResponse(__DIR__.'/../../templates/CarnetElectron/reader/libs/recorder/encoderWorker.min.wasm'); + $response = new StreamResponse(__DIR__.'/../../templates/CarnetWebClient/reader/libs/recorder/encoderWorker.min.wasm'); $response->addHeader("Content-Type", "application/wasm"); return $response; } @@ -332,7 +332,7 @@ public function getOpusEncoder(){ public function getUbuntuFont(){ $font = basename($_SERVER['REQUEST_URI']); if($font !== ".." && $font !== "../") - return new StreamResponse(__DIR__.'/../../templates/CarnetElectron/fonts/'.basename($_SERVER['REQUEST_URI'])); + return new StreamResponse(__DIR__.'/../../templates/CarnetWebClient/fonts/'.basename($_SERVER['REQUEST_URI'])); else die(); } @@ -344,7 +344,7 @@ public function getUbuntuFont(){ public function getMaterialFont(){ $font = basename($_SERVER['REQUEST_URI']); if($font !== ".." && $font !== "../") - return new StreamResponse(__DIR__.'/../../templates/CarnetElectron/fonts/'.basename($_SERVER['REQUEST_URI'])); + return new StreamResponse(__DIR__.'/../../templates/CarnetWebClient/fonts/'.basename($_SERVER['REQUEST_URI'])); else die(); } @@ -739,12 +739,14 @@ public function saveTextToOpenNote(){ $this->waitEndOfExtraction($id); $cache = $this->getCacheFolder(); $folder = $cache->get("currentnote".$id); + $mainFile = $_POST['isMarkdown'] ? "note.md" : "index.html"; try{ - $file = $folder->get("index.html"); + $file = $folder->get($mainFile); } catch(\OCP\Files\NotFoundException $e) { - $file = $folder->newFile("index.html"); + $file = $folder->newFile($mainFile); } $file->putContent($_POST['html']); + try{ $file = $folder->get("metadata.json"); } catch(\OCP\Files\NotFoundException $e) { @@ -752,7 +754,7 @@ public function saveTextToOpenNote(){ } $file->putContent($_POST['metadata']); $path = $_POST['path']; - $mtime = $this->saveFiles($folder, array(0 => "index.html", 1 =>"metadata.json"), $_POST['path'], $id); + $mtime = $this->saveFiles($folder, array(0 => $mainFile, 1 =>"metadata.json"), $_POST['path'], $id); if($mtime !== false){ //we need to refresh cache $cache = new CacheManager($this->db, $this->CarnetFolder); @@ -785,7 +787,7 @@ private function saveFiles($inFolder, $files, $path, $id){ return false; } } catch(\OCP\Files\NotFoundException $e) { - if($this->shouldUseFolderNotes()){ + if($this->shouldUseFolderNotes() || $_POST['isMarkdown']){ return $this->saveOpenNoteAsDir($inFolder, $files, $path, $id); } else { $this->saveOpenNote($_POST['path'],$id); @@ -905,6 +907,7 @@ public function deleteMediaFromOpenNote($id){ * @NoCSRFRequired */ public function addMediaToOpenNote($id){ + $path = $_POST['path']; $this->waitEndOfExtraction($id); $cache = $this->getCacheFolder(); $folder = $cache->get("currentnote".$id); @@ -999,7 +1002,7 @@ public function addMediaToOpenNote($id){ } if(!isset($meta['media'])) $meta['media'] = array(); - if(!in_array($meta['media'],$media)) + if(!in_array($media, $meta['media'])) array_push($meta['media'],$media); $cache->addToCache($path, $meta, $mtime, $text); @@ -1158,7 +1161,14 @@ public function openNote(){ try{ $noteNode = $this->CarnetFolder->get($path); if($noteNode->getType() === "dir"){ - $data['html'] = $noteNode->get('index.html')->getContent(); + if ($noteNode->nodeExists("note.md")){ + $data['html'] = $noteNode->get("note.md")->getContent(); + $data['isMarkdown'] = true; + } + else { + $data['html'] = $noteNode->get('index.html')->getContent(); + $data['isMarkdown'] = false; + } try{ $data['metadata'] = json_decode($noteNode->get('metadata.json')->getContent()); } catch(\OCP\Files\NotFoundException $e) { @@ -1177,6 +1187,7 @@ public function openNote(){ } } catch(\OCP\Files\NotFoundException $e) { $data["error"] = "not found"; + $data["isNew"] = true; } $data['id'] = $editUniqueID; @@ -1293,6 +1304,22 @@ public function update($id, $title, $content) { // empty for now } + public function useMDEditor(){ + return $this->Config->getUserValue($this->userId, $this->appName, "use_md_editor",0); + } + + /** + * @NoAdminRequired + * @NoCSRFRequired + */ + public function setUseMDEditor($useMD){ + if($useMD === "false") + $useMD = 0; + else if($useMD === "true") + $useMD = 1 ; + return $this->Config->setUserValue($this->userId, $this->appName, "use_md_editor", $useMD); + } + public function shouldUseFolderNotes(){ return $this->Config->getUserValue($this->userId, $this->appName, "should_use_folder_notes",false); } @@ -1329,16 +1356,16 @@ public function downloadArchive(){ * @NoCSRFRequired */ public function getAppThemes(){ - $root = $this->getCarnetElectronUrl()."/css/"; - return json_decode('[{"name":"Carnet", "path":"'.$this->getCarnetElectronPath().'/css/carnet", "preview":"'.$root.'carnet/preview.png"}, {"name":"Dark", "path":"'.$this->getCarnetElectronPath().'/css/dark", "preview":"'.$root.'dark/preview.png"}, {"name":"Black", "path":"'.$this->getCarnetElectronPath().'/css/black", "preview":"'.$root.'black/preview.png"}]'); + $root = $this->getCarnetWebClientUrl()."/css/"; + return json_decode('[{"name":"Carnet", "path":"'.$this->getCarnetWebClientPath().'/css/carnet", "preview":"'.$root.'carnet/preview.png"}, {"name":"Dark", "path":"'.$this->getCarnetWebClientPath().'/css/dark", "preview":"'.$root.'dark/preview.png"}, {"name":"Black", "path":"'.$this->getCarnetWebClientPath().'/css/black", "preview":"'.$root.'black/preview.png"}]'); } - private function getCarnetElectronPath(){ - return __DIR__.'/../../templates/CarnetElectron'; + private function getCarnetWebClientPath(){ + return __DIR__.'/../../templates/CarnetWebClient'; } - private function getCarnetElectronUrl(){ - $root = \OCP\Util::linkToAbsolute($this->appName,"templates")."/CarnetElectron"; + private function getCarnetWebClientUrl(){ + $root = \OCP\Util::linkToAbsolute($this->appName,"templates")."/CarnetWebClient"; if(strpos($root,"http://") === 0 && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'){ //should be https... $root = "https".substr($root,strlen("http")); @@ -1357,8 +1384,8 @@ public function setAppTheme($url){ $browser = array(); $editor = array(); $settings = array(); - if(strpos($url, $this->getCarnetElectronPath()) === 0){ - $url = $this->getCarnetElectronUrl().substr($url, strlen($this->getCarnetElectronPath()), strlen($url)); + if(strpos($url, $this->getCarnetWebClientPath()) === 0){ + $url = $this->getCarnetWebClientUrl().substr($url, strlen($this->getCarnetWebClientPath()), strlen($url)); } foreach($meta['browser'] as $css){ array_push($browser, $url."/".$css); diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 5051c2d..49d425c 100755 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -33,7 +33,7 @@ public function browser() { 'carnet_display_fullscreen' => $this->config->getAppValue('carnet', 'carnetDisplayFullscreen', 'no'), 'app_version' => OC_App::getAppInfo($this->appName)['version'], ]; - $response = new TemplateResponse($this->appName,"browser",$parameters); + $response = new TemplateResponse($this->appName,"new_browser",$parameters); $response->renderAs("blank"); $policy = new ContentSecurityPolicy(); $policy->addAllowedFrameDomain('\'self\''); @@ -78,7 +78,11 @@ public function writer() { $parameters = [ 'app_version' => OC_App::getAppInfo($this->appName)['version'], ]; - $response = new TemplateResponse($this->appName,"writer",$parameters); + if($this->config->getUserValue($this->userId, $this->appName, "use_md_editor",0)){ + $response = new TemplateResponse($this->appName,"new_editor",$parameters); + } + else + $response = new TemplateResponse($this->appName,"writer",$parameters); $policy = new ContentSecurityPolicy(); $policy->addAllowedMediaDomain('blob:'); $policy->addAllowedFrameDomain('\'self\''); diff --git a/release.sh b/release.sh index 93545b8..064e50e 100755 --- a/release.sh +++ b/release.sh @@ -38,6 +38,10 @@ rm carnet-*-v* cur=$(pwd) cp . ../tmpcarnet/carnet -R cd ../tmpcarnet/carnet/ + echo "Copying CarnetWebClient" + sudo rm templates/CarnetWebClient + cp ../../CarnetWebClient/dist templates/CarnetWebClient -R + echo "Cleaning" sudo rm .git -R sudo rm templates/CarnetElectron/.git -R sudo rm templates/CarnetElectron/node_modules/ -R diff --git a/templates/CarnetElectron b/templates/CarnetElectron index 99af0cf..e13a7fc 160000 --- a/templates/CarnetElectron +++ b/templates/CarnetElectron @@ -1 +1 @@ -Subproject commit 99af0cfa27c1413d50c5a7ba912ff4df3f804dbb +Subproject commit e13a7fc263e67089ecb25c7b399a1716062a6e23 diff --git a/templates/CarnetWebClient b/templates/CarnetWebClient new file mode 120000 index 0000000..45a3f1a --- /dev/null +++ b/templates/CarnetWebClient @@ -0,0 +1 @@ +/home/phieubuntu/Dev/Code/Carnet/CarnetWebClient/dist/ \ No newline at end of file diff --git a/templates/new_browser.php b/templates/new_browser.php new file mode 100644 index 0000000..7304e27 --- /dev/null +++ b/templates/new_browser.php @@ -0,0 +1,60 @@ +"; + +$file .= "".$_['requesttoken'].""; +if($_['carnet_display_fullscreen']==="yes"){ + + $file = str_replace('', " + + + getColorPrimary()."\"> + + ", $file); + if($_['nc_version']>=16) + style("carnet","../templates/CarnetWebClient/compatibility/nextcloud/nc16"); + +} +else { + if($_['nc_version']>=14) + style("carnet","../templates/CarnetWebClient/compatibility/nextcloud/nc14-header"); +} +$nonce = ""; +if (method_exists(\OC::$server, "getContentSecurityPolicyNonceManager")){ + $nonce = \OC::$server->getContentSecurityPolicyNonceManager()->getNonce(); +} +else{ + style("carnet","../templates/CarnetWebClient/compatibility/nextcloud/owncloud"); +} + +$file = str_replace("src=\"","defer nonce='".$nonce."' src=\"".$root."/CarnetWebClient/",$file); +echo $file; +echo "".$root."/CarnetWebClient/"; +?> diff --git a/templates/new_editor.php b/templates/new_editor.php new file mode 100644 index 0000000..1db3706 --- /dev/null +++ b/templates/new_editor.php @@ -0,0 +1,43 @@ +", $root."/CarnetWebClient/", $matches[2]); + $relativePath = str_replace("", "", $matches[2]); + return "", $root."/CarnetWebClient/", $matches[2]); + $relativePath = str_replace("", "", $matches[2]); + return "".$_['requesttoken'].""; + +$file = str_replace("", $root."/CarnetWebClient/", $file); +//$root = substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT'])); +$urlGenerator = \OC::$server->getURLGenerator(); +$file = str_replace("", $root."/CarnetWebClient/", $file); +if (method_exists(\OC::$server, "getContentSecurityPolicyNonceManager")){ + $nonce = \OC::$server->getContentSecurityPolicyNonceManager()->getNonce(); + $file = str_replace("src=\"","defer nonce='".$nonce."' src=\"",$file); +} +$file = str_replace("", parse_url($urlGenerator->linkToRouteAbsolute("carnet.page.index"), PHP_URL_PATH), $file); +echo $file; + +?> diff --git a/templates/settings.php b/templates/settings.php index c7d2a73..d02b75b 100755 --- a/templates/settings.php +++ b/templates/settings.php @@ -2,13 +2,13 @@ global $fullscreen; global $appVersion; $fullscreen = True; -$currentpath = __DIR__."/CarnetElectron/"; +$currentpath = __DIR__."/CarnetWebClient/"; $appVersion = $_['app_version']; $root = \OCP\Util::linkToAbsolute("carnet","templates"); $root = parse_url($root, PHP_URL_PATH); $file = file_get_contents($currentpath."settings.html"); -$file = str_replace("href=\"","href=\"".$root."/CarnetElectron/",$file); +$file = str_replace("href=\"","href=\"".$root."/CarnetWebClient/",$file); $file = preg_replace_callback('/"; if($_['nc_version']>=16) - style("carnet","../templates/CarnetElectron/compatibility/nextcloud/nc16"); + style("carnet","../templates/CarnetWebClient/compatibility/nextcloud/nc16"); } else if(isset ($_['nc_version']) && $_['nc_version']>=14) - style("carnet","../templates/CarnetElectron/compatibility/nextcloud/nc14-header"); + style("carnet","../templates/CarnetWebClient/compatibility/nextcloud/nc14-header"); $nonce = ""; if (method_exists(\OC::$server, "getContentSecurityPolicyNonceManager")){ $nonce = \OC::$server->getContentSecurityPolicyNonceManager()->getNonce(); } -$file = str_replace("src=\"","defer nonce='".$nonce."' src=\"".$root."/CarnetElectron/",$file); +$file = str_replace("src=\"","defer nonce='".$nonce."' src=\"".$root."/CarnetWebClient/",$file); echo $file; -echo "".$root."/CarnetElectron/"; +echo "".$root."/CarnetWebClient/"; echo "".urlencode(\OCP\Util::callRegister()).""; ?>