forked from projects/fipamo
page editing cleaned up, fixed date formatting, fixed page filtering, add Image API path
This commit is contained in:
parent
395850adb8
commit
1b9252fef0
14 changed files with 627 additions and 311 deletions
30
brain/api/v1/ImagesAPI.inc.php
Normal file
30
brain/api/v1/ImagesAPI.inc.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
class ImagesAPI
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function uploadImage($request)
|
||||
{
|
||||
$image = $request->getUploadedFiles();
|
||||
$path = date("Y") . "/" . date("m");
|
||||
|
||||
$uploadPath = "../public/assets/images/blog/" . $path;
|
||||
|
||||
FileUploader::uploadFile($uploadPath, $image["post_image"]);
|
||||
|
||||
$response = [
|
||||
"message" => "Image Added. Very slick",
|
||||
"type" => "postImageAdded",
|
||||
"url" =>
|
||||
"/assets/images/blog/" .
|
||||
$path .
|
||||
"/" .
|
||||
$image["post_image"]->getClientFileName(),
|
||||
];
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
//include "brain/data/Auth.inc.php";
|
||||
include "../brain/api/v1/ImagesAPI.inc.php";
|
||||
|
||||
class APIControl
|
||||
{
|
||||
|
@ -18,7 +18,6 @@ class APIControl
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$response->getBody()->write(json_encode($result));
|
||||
return $response->withHeader("Content-Type", "application/json");
|
||||
}
|
||||
|
@ -43,6 +42,33 @@ class APIControl
|
|||
break;
|
||||
case "logout":
|
||||
$result = Auth::logout($body);
|
||||
break;
|
||||
case "page":
|
||||
//move methdology to its own API class
|
||||
$task = $args["fourth"];
|
||||
$token = $request->getHeader("fipamo-access-token");
|
||||
if (Session::verifyToken($token[0])) {
|
||||
switch ($task) {
|
||||
case "delete":
|
||||
case "add":
|
||||
case "edit":
|
||||
$result = (new Book("../content/pages"))->editPage(
|
||||
$task,
|
||||
$request
|
||||
);
|
||||
break;
|
||||
|
||||
case "add-entry-image":
|
||||
$result = ImagesAPI::uploadImage($request);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$result = [
|
||||
"message" => "API access denied, homie",
|
||||
"type" => "API_ERROR",
|
||||
];
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
$result = [
|
||||
|
|
|
@ -18,7 +18,12 @@ class DashControl
|
|||
switch (isset($args["second"]) ? $args["second"] : "index") {
|
||||
case "pages":
|
||||
$currentPage = isset($args["fourth"]) ? $args["fourth"] : 1;
|
||||
$data = (new Book("../content/pages"))->getPages($currentPage, 4);
|
||||
$filter = isset($args["third"]) ? $args["third"] : "all";
|
||||
$data = (new Book("../content/pages"))->getPages(
|
||||
$currentPage,
|
||||
4,
|
||||
$filter
|
||||
);
|
||||
$template = "dash/book.twig";
|
||||
$pageOptions = [
|
||||
"entryCount" => $data["entryCount"],
|
||||
|
|
|
@ -33,23 +33,157 @@ class Book
|
|||
return $page;
|
||||
}
|
||||
|
||||
public function editPage($task, $request)
|
||||
{
|
||||
$content = $this->getContents();
|
||||
if ($task == "delete") {
|
||||
$parsed = json_decode(file_get_contents("php://input"), true);
|
||||
$body = find($content, ["uuid" => $parsed["id"]]);
|
||||
} else {
|
||||
$body = $request->getParsedBody();
|
||||
}
|
||||
|
||||
$page = find($content, ["uuid" => $body["uuid"]]);
|
||||
$image = $request->getUploadedFiles();
|
||||
$member = Session::get("member");
|
||||
|
||||
if ($task != "add") {
|
||||
$path =
|
||||
date("Y", date($page["rawCreated"])) .
|
||||
"/" .
|
||||
date("m", date($page["rawCreated"]));
|
||||
} else {
|
||||
$path = date("Y", date()) . "/" . date("m");
|
||||
}
|
||||
|
||||
if (isset($image["feature_image"])) {
|
||||
$feature = $image["feature_image"]->getClientFileName();
|
||||
FileUploader::uploadFile(
|
||||
"../public/assets/images/blog/" . $path . "/",
|
||||
$image["feature_image"]
|
||||
);
|
||||
} else {
|
||||
if (isset($body["feature_image"])) {
|
||||
$url = explode("/", $body["feature_image"]);
|
||||
$feature =
|
||||
"/" .
|
||||
$url[3] .
|
||||
"/" .
|
||||
$url[4] .
|
||||
"/" .
|
||||
$url[5] .
|
||||
"/" .
|
||||
$url[6] .
|
||||
"/" .
|
||||
$url[7] .
|
||||
"/" .
|
||||
$url[8];
|
||||
} else {
|
||||
$feature = $body["feature"];
|
||||
}
|
||||
}
|
||||
|
||||
if ($task == "delete") {
|
||||
$deleted = "true";
|
||||
$body["menu"] ? ($body["menu"] = "true") : ($body["menu"] = "false");
|
||||
$body["published"]
|
||||
? ($body["published"] = "true")
|
||||
: ($body["published"] = "false");
|
||||
$body["featured"]
|
||||
? ($body["featured"] = "true")
|
||||
: ($body["featured"] = "false");
|
||||
} else {
|
||||
$deleted = !$page["deleted"] ? "false" : $page["deleted"];
|
||||
}
|
||||
|
||||
$created =
|
||||
$task != "add"
|
||||
? new \Moment\Moment($page["rawCreated"])
|
||||
: new \Moment\Moment();
|
||||
$updated = new \Moment\Moment();
|
||||
|
||||
$write =
|
||||
"---\n" .
|
||||
"id: " .
|
||||
$body["id"] .
|
||||
"\n" .
|
||||
"uuid: " .
|
||||
$body["uuid"] .
|
||||
"\n" .
|
||||
"title: " .
|
||||
$body["title"] .
|
||||
"\n" .
|
||||
"feature: " .
|
||||
$feature .
|
||||
"\n" .
|
||||
"path: " .
|
||||
$path .
|
||||
"\n" .
|
||||
"layout: " .
|
||||
$body["layout"] .
|
||||
"\n" .
|
||||
"tags: " .
|
||||
$body["tags"] .
|
||||
"\n" .
|
||||
"author: " .
|
||||
$member["handle"] .
|
||||
"\n" .
|
||||
"created: " .
|
||||
$created->format("Y-m-d\TH:i:sP") .
|
||||
"\n" .
|
||||
"updated: " .
|
||||
$updated->format("Y-m-d\TH:i:sP") .
|
||||
"\n" .
|
||||
"deleted: " .
|
||||
$deleted .
|
||||
"\n" .
|
||||
"slug: " .
|
||||
$body["slug"] .
|
||||
"\n" .
|
||||
"menu: " .
|
||||
$body["menu"] .
|
||||
"\n" .
|
||||
"published: " .
|
||||
$body["published"] .
|
||||
"\n" .
|
||||
"featured: " .
|
||||
$body["featured"] .
|
||||
"\n---\n" .
|
||||
$body["content"];
|
||||
|
||||
// if layout is index, change path to file
|
||||
|
||||
if ($body["layout"] == "index") {
|
||||
$writePath = "../content/start/index.md";
|
||||
} else {
|
||||
$writePath = "../content/pages/" . $path . "/" . $body["slug"] . ".md";
|
||||
}
|
||||
|
||||
($new = fopen($writePath, "w")) or die("Unable to open file!");
|
||||
fwrite($new, $write);
|
||||
fclose($new);
|
||||
|
||||
$response = [
|
||||
"message" => "File edited. Nice work",
|
||||
"type" => $task == "write" ? "postUpdated" : "postAdded",
|
||||
];
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getPages(int $page, int $limit, string $sort = null)
|
||||
{
|
||||
$content = $this->getContents();
|
||||
|
||||
$published = filter($content, function ($item) {
|
||||
return $item["published"] == "true";
|
||||
return $item["published"] == true && $item["deleted"] == false;
|
||||
});
|
||||
$deleted = filter($content, function ($item) {
|
||||
return $item["deleted"];
|
||||
return $item["deleted"] == true;
|
||||
});
|
||||
|
||||
$all = $content;
|
||||
|
||||
$filter = isset($sort) ? $sort : "all";
|
||||
|
||||
//echo $filter;
|
||||
$filtered = [];
|
||||
switch ($filter) {
|
||||
case "published":
|
||||
$filtered = $published;
|
||||
|
@ -61,9 +195,7 @@ class Book
|
|||
$filtered = $content;
|
||||
break;
|
||||
}
|
||||
|
||||
$numOfPages = ceil(count($filtered) / $limit);
|
||||
|
||||
$folder = [];
|
||||
|
||||
if (count($filtered) != 0) {
|
||||
|
@ -99,7 +231,7 @@ class Book
|
|||
"numOfPages" => $numOfPages,
|
||||
"entryCount" => count($filtered),
|
||||
"paginate" => [
|
||||
"sort" => $filter,
|
||||
"sort" => $sort,
|
||||
"nextPage" => $next,
|
||||
"prevPage" => $prev,
|
||||
],
|
||||
|
@ -116,7 +248,6 @@ class Book
|
|||
$contents = [];
|
||||
foreach ($this->files as $file) {
|
||||
$doc = $parser->parse(file_get_contents($file), false);
|
||||
|
||||
$meta = $doc->getYAML();
|
||||
$page = [
|
||||
"id" => $meta["id"],
|
||||
|
@ -129,6 +260,8 @@ class Book
|
|||
"author" => $meta["author"],
|
||||
"created" => date("Y M D d", $meta["created"]),
|
||||
"updated" => date("Y M D d", $meta["updated"]),
|
||||
"rawCreated" => $meta["created"],
|
||||
"rawUpdated" => $meta["updated"],
|
||||
"deleted" => $meta["deleted"],
|
||||
"menu" => $meta["menu"],
|
||||
"featured" => $meta["featured"],
|
||||
|
@ -137,7 +270,6 @@ class Book
|
|||
"filePath" => $file,
|
||||
"content" => $doc->getContent(),
|
||||
];
|
||||
|
||||
//checks for duplicates
|
||||
$uuid = $meta["uuid"];
|
||||
$found = current(
|
||||
|
|
|
@ -38,6 +38,24 @@ class Session
|
|||
}
|
||||
}
|
||||
|
||||
public static function verifyToken($token)
|
||||
{
|
||||
$data = json_decode(file_get_contents(self::$file), true);
|
||||
if ($data["member"] != null) {
|
||||
$secret = (new Settings())->getFolks("secret");
|
||||
if (
|
||||
Token::validate($token, $secret) &&
|
||||
Token::validateExpiration($token, $secret)
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function set($key, $value)
|
||||
{
|
||||
$data = json_decode(file_get_contents(self::$file), true);
|
||||
|
|
29
brain/utility/FileUploader.inc.php
Normal file
29
brain/utility/FileUploader.inc.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
//include "brain/data/Auth.inc.php";
|
||||
|
||||
class FileUploader
|
||||
{
|
||||
public static function uploadFile(
|
||||
string $directory,
|
||||
UploadedFileInterface $file
|
||||
) {
|
||||
try {
|
||||
if (!is_dir($directory)) {
|
||||
//Directory does not exist, so lets create it.
|
||||
mkdir($directory, 0755, true);
|
||||
}
|
||||
//$upload = move_uploaded_file($file->getClientFileName(), $directory);
|
||||
//$extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
|
||||
|
||||
// see http://php.net/manual/en/function.random-bytes.php
|
||||
//$basename = bin2hex(random_bytes(8));
|
||||
//$filename = sprintf("%s.%0.8s", $basename, $extension);
|
||||
|
||||
$file->moveTo($directory . "/" . $file->getClientFileName());
|
||||
} catch (Error $e) {
|
||||
echo "failed to upload image: " . $e->getMessage();
|
||||
throw new Error("Failed to upload image file");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
{% set id = page['id'] %}
|
||||
{% set uuid = page['uuid'] %}
|
||||
{% set slug = page['slug'] %}
|
||||
{% set layout = page['layout'] %}
|
||||
{% set feature = page['feature'] %}
|
||||
{% set _title = page['title'] %}
|
||||
{% set tags = page['tags'] %}
|
||||
|
@ -16,6 +17,7 @@
|
|||
{% set id = '' %}
|
||||
{% set uuid = '' %}
|
||||
{% set slug = '' %}
|
||||
{% set layout = 'pages' %}
|
||||
{% set feature = '' %}
|
||||
{% set title = '' %}
|
||||
{% set tags = '' %}
|
||||
|
@ -32,7 +34,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block mainContent %}
|
||||
<div id="post-edit-index" data-index="{{ id }}" data-uuid="{{ uuid }}" data-slug="{{ slug }}">
|
||||
<div id="post-edit-index" data-index="{{ id }}" data-uuid="{{ uuid }}" data-slug="{{ slug }}" data-layout="{{ layout }}">
|
||||
<div id="post-edit-index-wrapper">
|
||||
<div id="post-feature">
|
||||
{% if page['feature'] == null %}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"slim/twig-view": "^3.0",
|
||||
"mnapoli/front-yaml": "^1.8",
|
||||
"lodash-php/lodash-php": "^0.0.7",
|
||||
"rbdwllr/reallysimplejwt": "^4.0"
|
||||
"rbdwllr/reallysimplejwt": "^4.0",
|
||||
"fightbulc/moment": "^1.33"
|
||||
}
|
||||
}
|
||||
|
|
59
composer.lock
generated
59
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "0e243f32e05cb4ef6265ce19f141fdae",
|
||||
"content-hash": "d5ef6d43f774049d093af6375d20ac11",
|
||||
"packages": [
|
||||
{
|
||||
"name": "erusev/parsedown",
|
||||
|
@ -112,6 +112,63 @@
|
|||
},
|
||||
"time": "2020-11-24T22:02:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fightbulc/moment",
|
||||
"version": "1.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fightbulc/moment.php.git",
|
||||
"reference": "435d68e481ab0a716358926fb51966e696d297e3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fightbulc/moment.php/zipball/435d68e481ab0a716358926fb51966e696d297e3",
|
||||
"reference": "435d68e481ab0a716358926fb51966e696d297e3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.5 || ^6.5 || ^7.5 || ^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Moment\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tino Ehrich",
|
||||
"email": "tino@bigpun.me",
|
||||
"role": "developer"
|
||||
}
|
||||
],
|
||||
"description": "Parse, validate, manipulate, and display dates in PHP w/ i18n support. Inspired by moment.js",
|
||||
"keywords": [
|
||||
"date",
|
||||
"display",
|
||||
"format",
|
||||
"i18n",
|
||||
"locale",
|
||||
"manipulate",
|
||||
"moment",
|
||||
"parse",
|
||||
"time",
|
||||
"translation",
|
||||
"validate"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/fightbulc/moment.php/issues",
|
||||
"source": "https://github.com/fightbulc/moment.php/tree/1.33.0"
|
||||
},
|
||||
"time": "2021-03-27T13:10:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "lodash-php/lodash-php",
|
||||
"version": "0.0.7",
|
||||
|
|
|
@ -11,13 +11,14 @@ include "../brain/controller/RouteControl.inc.php";
|
|||
include "../brain/data/Auth.inc.php";
|
||||
include "../brain/utility/StringTools.inc.php";
|
||||
include "../brain/data/Session.inc.php";
|
||||
include "../brain/utility/FileUploader.inc.php";
|
||||
|
||||
$app = AppFactory::create();
|
||||
$twig = Twig::create("../brain/views/");
|
||||
$app->add(TwigMiddleware::create($app, $twig));
|
||||
//set up routing
|
||||
$app->get("/[{first}[/{second}[/{third}[/{fourth}]]]]", "\RouteControl:get");
|
||||
$app->post("/[{first}[/{second}[/{third}[/{fourt}]]]]", "\RouteControl:post");
|
||||
$app->post("/[{first}[/{second}[/{third}[/{fourth}]]]]", "\RouteControl:post");
|
||||
//start the app
|
||||
|
||||
$app->run();
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
import PostIndex from './PostIndex';
|
||||
import SettingsIndex from './SettingsIndex';
|
||||
import NaviIndex from './NavIndex';
|
||||
import PostIndex from "./PostIndex";
|
||||
import SettingsIndex from "./SettingsIndex";
|
||||
import NaviIndex from "./NavIndex";
|
||||
|
||||
export default class DashManager {
|
||||
//--------------------------
|
||||
// constructor
|
||||
//--------------------------
|
||||
constructor() {
|
||||
this.currentDisplay = '';
|
||||
this.urlPieces = document.URL.split('/');
|
||||
this.chooseDisplay(this.urlPieces[5], this.urlPieces[6]);
|
||||
}
|
||||
//--------------------------
|
||||
// methods
|
||||
//--------------------------
|
||||
start() {}
|
||||
//--------------------------
|
||||
// constructor
|
||||
//--------------------------
|
||||
constructor() {
|
||||
this.currentDisplay = "";
|
||||
this.urlPieces = document.URL.split("/");
|
||||
this.chooseDisplay(this.urlPieces[4], this.urlPieces[5]);
|
||||
}
|
||||
//--------------------------
|
||||
// methods
|
||||
//--------------------------
|
||||
start() {}
|
||||
|
||||
chooseDisplay(section, page) {
|
||||
this.currentDisplay = '';
|
||||
switch (section) {
|
||||
case 'page':
|
||||
this.currentDisplay = new PostIndex(page);
|
||||
break;
|
||||
case 'settings':
|
||||
this.currentDisplay = new SettingsIndex();
|
||||
break;
|
||||
case 'navigation':
|
||||
this.currentDisplay = new NaviIndex();
|
||||
break;
|
||||
chooseDisplay(section, page) {
|
||||
this.currentDisplay = "";
|
||||
switch (section) {
|
||||
case "page":
|
||||
this.currentDisplay = new PostIndex(page);
|
||||
break;
|
||||
case "settings":
|
||||
this.currentDisplay = new SettingsIndex();
|
||||
break;
|
||||
case "navigation":
|
||||
this.currentDisplay = new NaviIndex();
|
||||
break;
|
||||
|
||||
default:
|
||||
//just chill
|
||||
break;
|
||||
}
|
||||
this.start();
|
||||
}
|
||||
//--------------------------
|
||||
// event handlers
|
||||
//--------------------------
|
||||
default:
|
||||
//just chill
|
||||
break;
|
||||
}
|
||||
this.start();
|
||||
}
|
||||
//--------------------------
|
||||
// event handlers
|
||||
//--------------------------
|
||||
}
|
||||
|
|
|
@ -1,70 +1,74 @@
|
|||
//TOOLS
|
||||
import FipamoAdminAPI, {
|
||||
TASK_PAGE_CREATE,
|
||||
TASK_PAGE_EDIT,
|
||||
TASK_PAGE_DELETE
|
||||
} from '../../libraries/FipamoAdminAPI';
|
||||
import * as DataEvent from '../events/DataEvent';
|
||||
import PageActions from '../actions/PageActions';
|
||||
import * as EditorEvent from '../events/EditorEvent';
|
||||
TASK_PAGE_CREATE,
|
||||
TASK_PAGE_EDIT,
|
||||
TASK_PAGE_DELETE,
|
||||
} from "../../libraries/FipamoAdminAPI";
|
||||
import * as DataEvent from "../events/DataEvent";
|
||||
import PageActions from "../actions/PageActions";
|
||||
import * as EditorEvent from "../events/EditorEvent";
|
||||
//import TinyDatePicker from 'tiny-date-picker';
|
||||
import TextEditor from '../ui/TextEditor';
|
||||
import Notfications from '../ui/Notifications';
|
||||
import TextEditor from "../ui/TextEditor";
|
||||
import Notfications from "../ui/Notifications";
|
||||
const admin = new FipamoAdminAPI();
|
||||
const notify = new Notfications();
|
||||
export default class PostEditor {
|
||||
//--------------------------
|
||||
// constructor
|
||||
//--------------------------
|
||||
constructor() {
|
||||
let self = this;
|
||||
this.urlPieces = document.URL.split('/');
|
||||
this.post = [];
|
||||
this.postID = null;
|
||||
this.postUUID = null;
|
||||
this.postLayout = null;
|
||||
if (document.getElementById('post-edit-index').getAttribute('data-index')) {
|
||||
this.postID = document.getElementById('post-edit-index').getAttribute('data-index');
|
||||
this.postUUID = document.getElementById('post-edit-index').getAttribute('data-uuid');
|
||||
this.postLayout = document
|
||||
.getElementById('post-edit-index')
|
||||
.getAttribute('data-layout');
|
||||
}
|
||||
if (document.getElementById('edit-post-text')) {
|
||||
this.editor = new TextEditor(
|
||||
document.getElementById('edit-post-text'),
|
||||
document.getElementById('header').offsetHeight +
|
||||
document.getElementById('post-header').offsetHeight +
|
||||
document.getElementById('post-feature').offsetHeight
|
||||
);
|
||||
this.editor.addListener(
|
||||
EditorEvent.EDITOR_DELETE,
|
||||
() => this.handleEditorOptions(EditorEvent.EDITOR_DELETE),
|
||||
false
|
||||
);
|
||||
this.editor.addListener(
|
||||
EditorEvent.EDITOR_UPLOAD_POST_IMAGE,
|
||||
() => this.handleEditorOptions(EditorEvent.EDITOR_UPLOAD_POST_IMAGE),
|
||||
false
|
||||
);
|
||||
this.editor.addListener(
|
||||
EditorEvent.EDITOR_UPDATE,
|
||||
() => this.handleEditorOptions(EditorEvent.EDITOR_UPDATE),
|
||||
false
|
||||
);
|
||||
this.editor.addListener(
|
||||
EditorEvent.EDITOR_SAVE,
|
||||
() => this.handleEditorOptions(EditorEvent.EDITOR_SAVE),
|
||||
false
|
||||
);
|
||||
document.getElementById('post-image-upload').addEventListener(
|
||||
'change',
|
||||
e => {
|
||||
self.handleImageUpload(e.target.id, e.target.files);
|
||||
},
|
||||
false
|
||||
);
|
||||
/*
|
||||
//--------------------------
|
||||
// constructor
|
||||
//--------------------------
|
||||
constructor() {
|
||||
let self = this;
|
||||
this.urlPieces = document.URL.split("/");
|
||||
this.post = [];
|
||||
this.postID = null;
|
||||
this.postUUID = null;
|
||||
this.postLayout = null;
|
||||
if (document.getElementById("post-edit-index").getAttribute("data-index")) {
|
||||
this.postID = document
|
||||
.getElementById("post-edit-index")
|
||||
.getAttribute("data-index");
|
||||
this.postUUID = document
|
||||
.getElementById("post-edit-index")
|
||||
.getAttribute("data-uuid");
|
||||
this.postLayout = document
|
||||
.getElementById("post-edit-index")
|
||||
.getAttribute("data-layout");
|
||||
}
|
||||
if (document.getElementById("edit-post-text")) {
|
||||
this.editor = new TextEditor(
|
||||
document.getElementById("edit-post-text"),
|
||||
document.getElementById("header").offsetHeight +
|
||||
document.getElementById("post-header").offsetHeight +
|
||||
document.getElementById("post-feature").offsetHeight
|
||||
);
|
||||
this.editor.addListener(
|
||||
EditorEvent.EDITOR_DELETE,
|
||||
() => this.handleEditorOptions(EditorEvent.EDITOR_DELETE),
|
||||
false
|
||||
);
|
||||
this.editor.addListener(
|
||||
EditorEvent.EDITOR_UPLOAD_POST_IMAGE,
|
||||
() => this.handleEditorOptions(EditorEvent.EDITOR_UPLOAD_POST_IMAGE),
|
||||
false
|
||||
);
|
||||
this.editor.addListener(
|
||||
EditorEvent.EDITOR_UPDATE,
|
||||
() => this.handleEditorOptions(EditorEvent.EDITOR_UPDATE),
|
||||
false
|
||||
);
|
||||
this.editor.addListener(
|
||||
EditorEvent.EDITOR_SAVE,
|
||||
() => this.handleEditorOptions(EditorEvent.EDITOR_SAVE),
|
||||
false
|
||||
);
|
||||
document.getElementById("post-image-upload").addEventListener(
|
||||
"change",
|
||||
(e) => {
|
||||
self.handleImageUpload(e.target.id, e.target.files);
|
||||
},
|
||||
false
|
||||
);
|
||||
/*
|
||||
TinyDatePicker(document.getElementById('post-date'), {
|
||||
mode: 'dp-below',
|
||||
format() {
|
||||
|
@ -73,170 +77,180 @@ export default class PostEditor {
|
|||
});
|
||||
*/
|
||||
|
||||
this.start();
|
||||
}
|
||||
}
|
||||
//--------------------------
|
||||
// methods
|
||||
//--------------------------
|
||||
start() {
|
||||
if (document.getElementById('featured-image-drop')) {
|
||||
document
|
||||
.getElementById('featured-image-drop')
|
||||
.addEventListener('dragover', this.handleImageActions, false);
|
||||
document
|
||||
.getElementById('featured-image-drop')
|
||||
.addEventListener('drop', this.handleImageActions, false);
|
||||
document
|
||||
.getElementById('featured-image-upload')
|
||||
.addEventListener('change', e => this.handleImageActions(e), false);
|
||||
if (document.getElementById('new-feature-upload')) {
|
||||
document.getElementById('new-feature-upload').addEventListener('click', () => {
|
||||
document.getElementById('featured-image-upload').click();
|
||||
});
|
||||
}
|
||||
var optionButtons = document.querySelectorAll('.post-option-btn');
|
||||
for (var i = 0, length = optionButtons.length; i < length; i++) {
|
||||
optionButtons[i].addEventListener('click', e => this.handlePostOptions(e), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------
|
||||
// event handlers
|
||||
//--------------------------
|
||||
handlePostOptions(e) {
|
||||
let currentOption;
|
||||
switch (e.target.id) {
|
||||
case 'option-page-icon':
|
||||
case 'option-menu-pin':
|
||||
currentOption = document.getElementById('option-menu-pin');
|
||||
break;
|
||||
case 'option-feature-icon':
|
||||
case 'option-feature':
|
||||
currentOption = document.getElementById('option-feature');
|
||||
break;
|
||||
case 'option-published-icon':
|
||||
case 'option-published':
|
||||
currentOption = document.getElementById('option-published');
|
||||
break;
|
||||
}
|
||||
let active = currentOption.getAttribute('data-active');
|
||||
active == 'false'
|
||||
? currentOption.setAttribute('data-active', 'true')
|
||||
: currentOption.setAttribute('data-active', 'false');
|
||||
}
|
||||
handleEditorOptions(e) {
|
||||
switch (e) {
|
||||
case EditorEvent.EDITOR_SAVE:
|
||||
case EditorEvent.EDITOR_UPDATE:
|
||||
var task = '';
|
||||
e === EditorEvent.EDITOR_SAVE ? (task = TASK_PAGE_CREATE) : (task = TASK_PAGE_EDIT);
|
||||
new PageActions()
|
||||
.collectInfo(document.getElementById('featured-image-upload').files[0])
|
||||
.then(page => {
|
||||
notify.alert('Writing down changes', null);
|
||||
admin
|
||||
.pageActions(task, page)
|
||||
.then(r => {
|
||||
if (
|
||||
r.type === DataEvent.PAGE_ERROR ||
|
||||
r.type === DataEvent.API_REQUEST_LAME
|
||||
) {
|
||||
notify.alert(r.message, false);
|
||||
} else {
|
||||
if (r.type === DataEvent.PAGE_UPDATED) {
|
||||
notify.alert(r.message, true);
|
||||
} else {
|
||||
notify.alert(r.message, true);
|
||||
window.location = '/@/dashboard/page/edit/' + r.id;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
notify.alert(err, false);
|
||||
});
|
||||
});
|
||||
break;
|
||||
case EditorEvent.EDITOR_DELETE:
|
||||
if (this.postLayout === 'index') {
|
||||
notify.alert('Index cannot be deleted', false);
|
||||
return;
|
||||
}
|
||||
if (confirm("AYE! You know you're deleting this post, right?")) {
|
||||
let id = { id: this.postUUID };
|
||||
admin
|
||||
.pageActions(TASK_PAGE_DELETE, id)
|
||||
.then(() => {
|
||||
window.location = '/@/dashboard/page/list/';
|
||||
})
|
||||
.catch(err => {
|
||||
notify.alert(err, false);
|
||||
});
|
||||
} else {
|
||||
// Do nothing!
|
||||
}
|
||||
break;
|
||||
case EditorEvent.EDITOR_UPLOAD_POST_IMAGE:
|
||||
document.getElementById('post-image-upload').click();
|
||||
break;
|
||||
}
|
||||
}
|
||||
handleImageActions(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
switch (e.type) {
|
||||
case 'dragover':
|
||||
e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
|
||||
break;
|
||||
case 'change':
|
||||
case 'drop':
|
||||
e.type == 'drop'
|
||||
? (PostEditor.uploadFiles = e.dataTransfer.files)
|
||||
: (PostEditor.uploadFiles = e.target.files);
|
||||
for (var i = 0, f; (f = PostEditor.uploadFiles[i]); i++) {
|
||||
// Only process image files.
|
||||
if (!f.type.match('image.*')) {
|
||||
continue;
|
||||
}
|
||||
var reader = new FileReader();
|
||||
// Closure to capture the file information.
|
||||
reader.onload = (function (theFile) {
|
||||
return function (f) {
|
||||
// Render thumbnail.
|
||||
var image = document.createElement('img');
|
||||
image.src = f.target.result;
|
||||
image.title = escape(theFile.name);
|
||||
var span = document.createElement('div');
|
||||
span.innerHTML = [
|
||||
'<img src="',
|
||||
f.target.result,
|
||||
'" title="',
|
||||
escape(theFile.name),
|
||||
'"/>'
|
||||
].join('');
|
||||
document.getElementById('featured-image-drop').innerHTML = '';
|
||||
document.getElementById('featured-image-drop').appendChild(image);
|
||||
};
|
||||
})(f);
|
||||
// Read in the image file as a data URL.
|
||||
reader.readAsDataURL(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
handleImageUpload(type, files) {
|
||||
let self = this;
|
||||
notify.alert('Uploading Image', null);
|
||||
admin
|
||||
.imageUpload(type, files)
|
||||
.then(r => {
|
||||
if (r.type == DataEvent.POST_IMAGE_ADDED)
|
||||
self.editor.notify(EditorEvent.EDITOR_UPLOAD_POST_IMAGE, r.url);
|
||||
notify.alert('Image Added to Entry', true);
|
||||
})
|
||||
.catch(() => {
|
||||
notify.alert('Uh oh. Image not added', false);
|
||||
//console.log('ERROR', err);
|
||||
});
|
||||
}
|
||||
this.start();
|
||||
}
|
||||
}
|
||||
//--------------------------
|
||||
// methods
|
||||
//--------------------------
|
||||
start() {
|
||||
if (document.getElementById("featured-image-drop")) {
|
||||
document
|
||||
.getElementById("featured-image-drop")
|
||||
.addEventListener("dragover", this.handleImageActions, false);
|
||||
document
|
||||
.getElementById("featured-image-drop")
|
||||
.addEventListener("drop", this.handleImageActions, false);
|
||||
document
|
||||
.getElementById("featured-image-upload")
|
||||
.addEventListener("change", (e) => this.handleImageActions(e), false);
|
||||
if (document.getElementById("new-feature-upload")) {
|
||||
document
|
||||
.getElementById("new-feature-upload")
|
||||
.addEventListener("click", () => {
|
||||
document.getElementById("featured-image-upload").click();
|
||||
});
|
||||
}
|
||||
var optionButtons = document.querySelectorAll(".post-option-btn");
|
||||
for (var i = 0, length = optionButtons.length; i < length; i++) {
|
||||
optionButtons[i].addEventListener(
|
||||
"click",
|
||||
(e) => this.handlePostOptions(e),
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------
|
||||
// event handlers
|
||||
//--------------------------
|
||||
handlePostOptions(e) {
|
||||
let currentOption;
|
||||
switch (e.target.id) {
|
||||
case "option-page-icon":
|
||||
case "option-menu-pin":
|
||||
currentOption = document.getElementById("option-menu-pin");
|
||||
break;
|
||||
case "option-feature-icon":
|
||||
case "option-feature":
|
||||
currentOption = document.getElementById("option-feature");
|
||||
break;
|
||||
case "option-published-icon":
|
||||
case "option-published":
|
||||
currentOption = document.getElementById("option-published");
|
||||
break;
|
||||
}
|
||||
let active = currentOption.getAttribute("data-active");
|
||||
active == "false"
|
||||
? currentOption.setAttribute("data-active", "true")
|
||||
: currentOption.setAttribute("data-active", "false");
|
||||
}
|
||||
handleEditorOptions(e) {
|
||||
switch (e) {
|
||||
case EditorEvent.EDITOR_SAVE:
|
||||
case EditorEvent.EDITOR_UPDATE:
|
||||
var task = "";
|
||||
e === EditorEvent.EDITOR_SAVE
|
||||
? (task = TASK_PAGE_CREATE)
|
||||
: (task = TASK_PAGE_EDIT);
|
||||
new PageActions()
|
||||
.collectInfo(
|
||||
document.getElementById("featured-image-upload").files[0]
|
||||
)
|
||||
.then((page) => {
|
||||
notify.alert("Writing down changes", null);
|
||||
admin
|
||||
.pageActions(task, page)
|
||||
.then((r) => {
|
||||
if (
|
||||
r.type === DataEvent.PAGE_ERROR ||
|
||||
r.type === DataEvent.API_REQUEST_LAME
|
||||
) {
|
||||
notify.alert(r.message, false);
|
||||
} else {
|
||||
if (r.type === DataEvent.PAGE_UPDATED) {
|
||||
notify.alert(r.message, true);
|
||||
} else {
|
||||
notify.alert(r.message, true);
|
||||
window.location = "/@/dashboard/page/edit/" + r.id;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
notify.alert(err, false);
|
||||
});
|
||||
});
|
||||
break;
|
||||
case EditorEvent.EDITOR_DELETE:
|
||||
if (this.postLayout === "index") {
|
||||
notify.alert("Index cannot be deleted", false);
|
||||
return;
|
||||
}
|
||||
if (confirm("AYE! You know you're deleting this post, right?")) {
|
||||
let id = { id: this.postUUID };
|
||||
admin
|
||||
.pageActions(TASK_PAGE_DELETE, id)
|
||||
.then(() => {
|
||||
window.location = "/dashboard/pages";
|
||||
})
|
||||
.catch((err) => {
|
||||
notify.alert(err, false);
|
||||
});
|
||||
} else {
|
||||
// Do nothing!
|
||||
}
|
||||
break;
|
||||
case EditorEvent.EDITOR_UPLOAD_POST_IMAGE:
|
||||
document.getElementById("post-image-upload").click();
|
||||
break;
|
||||
}
|
||||
}
|
||||
handleImageActions(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
switch (e.type) {
|
||||
case "dragover":
|
||||
e.dataTransfer.dropEffect = "copy"; // Explicitly show this is a copy.
|
||||
break;
|
||||
case "change":
|
||||
case "drop":
|
||||
e.type == "drop"
|
||||
? (PostEditor.uploadFiles = e.dataTransfer.files)
|
||||
: (PostEditor.uploadFiles = e.target.files);
|
||||
for (var i = 0, f; (f = PostEditor.uploadFiles[i]); i++) {
|
||||
// Only process image files.
|
||||
if (!f.type.match("image.*")) {
|
||||
continue;
|
||||
}
|
||||
var reader = new FileReader();
|
||||
// Closure to capture the file information.
|
||||
reader.onload = (function (theFile) {
|
||||
return function (f) {
|
||||
// Render thumbnail.
|
||||
var image = document.createElement("img");
|
||||
image.src = f.target.result;
|
||||
image.title = escape(theFile.name);
|
||||
var span = document.createElement("div");
|
||||
span.innerHTML = [
|
||||
'<img src="',
|
||||
f.target.result,
|
||||
'" title="',
|
||||
escape(theFile.name),
|
||||
'"/>',
|
||||
].join("");
|
||||
document.getElementById("featured-image-drop").innerHTML = "";
|
||||
document.getElementById("featured-image-drop").appendChild(image);
|
||||
};
|
||||
})(f);
|
||||
// Read in the image file as a data URL.
|
||||
reader.readAsDataURL(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
handleImageUpload(type, files) {
|
||||
let self = this;
|
||||
notify.alert("Uploading Image", null);
|
||||
admin
|
||||
.imageUpload(type, files)
|
||||
.then((r) => {
|
||||
if (r.type == DataEvent.POST_IMAGE_ADDED)
|
||||
self.editor.notify(EditorEvent.EDITOR_UPLOAD_POST_IMAGE, r.url);
|
||||
notify.alert("Image Added to Entry", true);
|
||||
})
|
||||
.catch(() => {
|
||||
notify.alert("Uh oh. Image not added", false);
|
||||
//console.log('ERROR', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
PostEditor.uploadFiles = [];
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
import PageEditor from './PageEditor';
|
||||
import PageEditor from "./PageEditor";
|
||||
export default class PostIndex {
|
||||
//--------------------------
|
||||
// constructor
|
||||
//--------------------------
|
||||
constructor(page) {
|
||||
this.currentPage = null;
|
||||
this.choosePage(page);
|
||||
this.start();
|
||||
}
|
||||
//--------------------------
|
||||
// methods
|
||||
//--------------------------
|
||||
start() {}
|
||||
choosePage(page) {
|
||||
this.currentPage = '';
|
||||
switch (page) {
|
||||
case 'edit':
|
||||
case 'add':
|
||||
this.currentPage = new PageEditor();
|
||||
break;
|
||||
default:
|
||||
//just chill
|
||||
break;
|
||||
}
|
||||
}
|
||||
//--------------------------
|
||||
// event handlers
|
||||
//--------------------------
|
||||
//--------------------------
|
||||
// constructor
|
||||
//--------------------------
|
||||
constructor(page) {
|
||||
this.currentPage = null;
|
||||
this.choosePage(page);
|
||||
this.start();
|
||||
}
|
||||
//--------------------------
|
||||
// methods
|
||||
//--------------------------
|
||||
start() {}
|
||||
choosePage(page) {
|
||||
this.currentPage = "";
|
||||
switch (page) {
|
||||
case "edit":
|
||||
case "add":
|
||||
this.currentPage = new PageEditor();
|
||||
break;
|
||||
default:
|
||||
//just chill
|
||||
break;
|
||||
}
|
||||
}
|
||||
//--------------------------
|
||||
// event handlers
|
||||
//--------------------------
|
||||
}
|
||||
|
|
|
@ -9,10 +9,10 @@ export const CONTENT_TYPE_JSON = "json";
|
|||
export const CONTENT_TYPE_FORM = "x-www-form-urlencoded";
|
||||
export const API_STATUS = "/api/v1/status";
|
||||
export const API_GET_NAV = "/api/settings/nav";
|
||||
export const API_NEW_PAGE = "/api/v1/page/write/new";
|
||||
export const API_NEW_PAGE = "/api/v1/page/create";
|
||||
export const API_EDIT_PAGE = "/api/v1/page/write";
|
||||
export const API_DELETE_PAGE = "/api/v1/page/delete";
|
||||
export const API_IMAGE_UPLOAD = "/api/v1/page/add-post-image";
|
||||
export const API_IMAGE_UPLOAD = "/api/v1/page/add-entry-image";
|
||||
export const API_SETTINGS_SYNC = "/api/v1/settings/sync";
|
||||
export const API_UPLOAD_AVATAR = "/api/v1/settings/add-avatar";
|
||||
export const API_UPLOAD_BACKGROUND = "/api/v1/settings/add-feature-background";
|
||||
|
@ -280,6 +280,7 @@ export default class APIUtils {
|
|||
request.open(requestType, requestURL, true);
|
||||
request.onload = () => {
|
||||
if (request.status == 200) {
|
||||
//console.log("RESPONSE", request);
|
||||
let response = JSON.parse(request["response"]);
|
||||
resolve(response);
|
||||
} else {
|
||||
|
@ -298,7 +299,7 @@ export default class APIUtils {
|
|||
eventType === DataEvent.API_BACKUP_RESTORE ||
|
||||
eventType === DataEvent.API_REINDEX_PAGES
|
||||
)
|
||||
request.setRequestHeader("x-access-token", self.token);
|
||||
request.setRequestHeader("fipamo-access-token", self.token);
|
||||
|
||||
switch (contentType) {
|
||||
case CONTENT_TYPE_JSON:
|
||||
|
|
Loading…
Reference in a new issue