[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [websites/paste-kde-org/dev-1.0] /: Add AJAX and JS bits and admin dashboard
From: Sayak Banerjee <sayakb () kde ! org>
Date: 2013-09-01 7:16:51
Message-ID: E1VG1tz-0004SC-CQ () scm ! kde ! org
[Download RAW message or body]
Git commit cc5c21a9324e9a4d0dd11d10b462f0401aad1a85 by Sayak Banerjee.
Committed on 01/09/2013 at 07:16.
Pushed by sayakb into branch 'dev-1.0'.
Add AJAX and JS bits and admin dashboard
M +12 -0 app/config/app.php
A +16 -0 app/config/googlesvc.php
M +1 -1 app/config/menus.php
M +43 -1 app/controllers/AjaxController.php
M +16 -3 app/controllers/CreateController.php
A +18 -0 app/lang/en/ajax.php
A +102 -0 app/lib/GoogleSvc.php
M +4 -4 app/views/admin/dashboard.blade.php
A +4 -0 app/views/ajax/version/ok.blade.php
A +4 -0 app/views/ajax/version/old.blade.php
M +1 -1 app/views/site/create.blade.php
M +6 -2 app/views/site/show.blade.php
M +1 -0 public/assets/css/stickynotes.css
M +114 -16 public/assets/js/stickynotes.js
M +1 -1 vendor/autoload.php
M +2 -0 vendor/composer/autoload_classmap.php
M +3 -3 vendor/composer/autoload_real.php
http://commits.kde.org/websites/paste-kde-org/cc5c21a9324e9a4d0dd11d10b462f0401aad1a85
diff --git a/app/config/app.php b/app/config/app.php
index 34dae91..5fd8eb1 100755
--- a/app/config/app.php
+++ b/app/config/app.php
@@ -11,10 +11,22 @@ return array(
| this value to have the update checker keep working as expected.
|
*/
+
'version' => '1.0.0',
/*
|--------------------------------------------------------------------------
+ | Sticky Notes update URL
+ |--------------------------------------------------------------------------
+ |
+ | The update checker will use this URL to get the latest version.
+ |
+ */
+
+ 'updateUrl' => 'http://sayakb.github.io/sticky-notes/version/',
+
+ /*
+ |--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
diff --git a/app/config/googlesvc.php b/app/config/googlesvc.php
new file mode 100644
index 0000000..01f53a0
--- /dev/null
+++ b/app/config/googlesvc.php
@@ -0,0 +1,16 @@
+<?php
+
+return array(
+
+ /*
+ |--------------------------------------------------------------------------
+ | Google services configuration
+ |--------------------------------------------------------------------------
+ |
+ | This file holds URLs to interact with google services
+ |
+ */
+
+ 'urlshortener' => 'https://www.googleapis.com/urlshortener/v1/url?key=%s',
+
+);
diff --git a/app/config/menus.php b/app/config/menus.php
index 12b611c..b38586d 100755
--- a/app/config/menus.php
+++ b/app/config/menus.php
@@ -98,7 +98,7 @@ return array(
'admin/dashboard' => array(
'label' => 'admin.dashboard',
- 'icon' => 'dashboard',
+ 'icon' => 'home',
'role' => 'admin'
),
diff --git a/app/controllers/AjaxController.php b/app/controllers/AjaxController.php
index cafea03..4a0f3ad 100755
--- a/app/controllers/AjaxController.php
+++ b/app/controllers/AjaxController.php
@@ -28,11 +28,23 @@ class AjaxController extends BaseController {
/**
* Fetches the latest available sticky notes version
*
- * @return string
+ * @return \Illuminate\View\View
*/
public function getVersion()
{
+ // Get app configuration
+ $app = Config::get('app');
+
+ // Parse the version number to unified numeral format
+ $localVersion = str_replace('.', '', $app['version']);
+
+ // Get the remote version number
+ $remoteVersion = @file_get_contents($app['updateUrl']);
+
+ // Compare the versions and return the appropriate response
+ $view = intval($remoteVersion) > intval($localVersion) ? 'old' : 'ok';
+ return View::make("ajax/version/{$view}");
}
/**
@@ -45,4 +57,34 @@ class AjaxController extends BaseController {
return Site::getSystemLoad();
}
+ /**
+ * Generates a short URL for a paste
+ *
+ * @param string $urlkey
+ * @param string $hash = ''
+ * @return \Illuminate\View\View|string
+ */
+ public function getShorten($urlkey, $hash = '')
+ {
+ // We need to validate the paste first
+ $paste = Paste::where('urlkey', $urlkey)->first();
+
+ // Paste was not found
+ if (is_null($paste))
+ {
+ return Lang::get('ajax.error');
+ }
+
+ // If it is a private paste, we need the hash
+ if ($paste->private AND $paste->hash != $hash)
+ {
+ return Lang::get('ajax.error');
+ }
+
+ // Shorten and return the paste URL
+ $longUrl = url("{$urlkey}/{$hash}");
+
+ return GoogleSvc::urlshortener($longUrl);
+ }
+
}
diff --git a/app/controllers/CreateController.php b/app/controllers/CreateController.php
index d6d1526..4e143e3 100755
--- a/app/controllers/CreateController.php
+++ b/app/controllers/CreateController.php
@@ -34,13 +34,21 @@ class CreateController extends BaseController {
*/
public function getCreate()
{
+ // Build the view data
$data = array(
'languages' => Highlighter::make()->languages(),
+ 'language' => 'text',
'paste' => new Paste,
'action' => 'CreateController@postCreate',
'disabled' => '',
);
+ // Get the default language from cookie
+ if (Cookie::has('language'))
+ {
+ $data['language'] = Cookie::get('language');
+ }
+
return View::make('site/create', $data, Site::defaults());
}
@@ -68,6 +76,10 @@ class CreateController extends BaseController {
// Execute antispam services
$resultAntispam = $antispam->passes();
+ // Save the language as a cookie so that it is auto
+ // selected next time
+ $cookie = Cookie::forever('language', Input::get('language'));
+
if ($resultValidation AND $resultAntispam)
{
// We inject the project into the input so that
@@ -89,11 +101,11 @@ class CreateController extends BaseController {
}
else if ($paste->private)
{
- return Redirect::to("{$paste->urlkey}/{$paste->hash}");
+ return Redirect::to("{$paste->urlkey}/{$paste->hash}")->withCookie($cookie);
}
else
{
- return Redirect::to($paste->urlkey);
+ return Redirect::to($paste->urlkey)->withCookie($cookie);
}
}
else
@@ -109,7 +121,7 @@ class CreateController extends BaseController {
}
}
- return Redirect::to(URL::previous())->withInput();
+ return Redirect::to(URL::previous())->withInput()->withCookie($cookie);
}
/**
@@ -146,6 +158,7 @@ class CreateController extends BaseController {
// Output the view
$data = array(
'languages' => Highlighter::make()->languages(),
+ 'language' => 'text',
'paste' => $paste,
'action' => 'CreateController@postRevision',
'disabled' => 'disabled',
diff --git a/app/lang/en/ajax.php b/app/lang/en/ajax.php
new file mode 100755
index 0000000..c1aaca1
--- /dev/null
+++ b/app/lang/en/ajax.php
@@ -0,0 +1,18 @@
+<?php
+
+return array(
+
+ /*
+ |--------------------------------------------------------------------------
+ | AJAX module language lines
+ |--------------------------------------------------------------------------
+ |
+ | This file defines languages lines for the AJAX requests
+ |
+ */
+
+ "version_ok" => "You have the latest version of Sticky Notes",
+ "version_old" => "A newer version of Sticky Notes is available",
+ "error" => "Error",
+
+);
diff --git a/app/lib/GoogleSvc.php b/app/lib/GoogleSvc.php
new file mode 100755
index 0000000..24da373
--- /dev/null
+++ b/app/lib/GoogleSvc.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * Sticky Notes
+ *
+ * An open source lightweight pastebin application
+ *
+ * @package StickyNotes
+ * @author Sayak Banerjee
+ * @copyright (c) 2013 Sayak Banerjee <mail@sayakbanerjee.com>
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ * @link http://sayakbanerjee.com/sticky-notes
+ * @since Version 1.0
+ * @filesource
+ */
+
+/**
+ * GoogleSvc class
+ *
+ * Layer for accessing Google APIs
+ *
+ * @package StickyNotes
+ * @subpackage Libraries
+ * @author Sayak Banerjee
+ */
+class GoogleSvc {
+
+ /**
+ * goo.gl URL shortener service
+ *
+ * @static
+ * @param string $longUrl
+ * @return string
+ */
+ public static function urlshortener($longUrl)
+ {
+ $apiUrl = static::getServiceUrl('urlshortener');
+
+ if ( ! is_null($apiUrl))
+ {
+ $ch = curl_init();
+
+ // Set the API url to connect to
+ curl_setopt($ch, CURLOPT_URL, $apiUrl);
+
+ // We will be making a POST request
+ curl_setopt($ch, CURLOPT_POST, TRUE);
+
+ // Set the URL that we want to shorten
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array("longUrl" => $longUrl)));
+
+ // Indicate that we want the response in JSON format
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
+
+ // Indicate that we want a text response back
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+
+ // This is just in case the SSL certificate is not valid
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+
+ // Execute the POST request
+ $result = curl_exec($ch);
+
+ curl_close($ch);
+
+ // Parse and return the response
+ $response = json_decode($result, TRUE);
+
+ if (isset($response['id']))
+ {
+ return $response['id'];
+ }
+ }
+
+ return Lang::get('ajax.error');
+ }
+
+ /**
+ * Returns the service URL for a specific service
+ *
+ * @static
+ * @param string $service
+ * @return string
+ */
+ private static function getServiceUrl($service)
+ {
+ // Get the service URL
+ $urls = Config::get('googlesvc');
+
+ // Get the site configuration
+ $site = Site::config('general');
+
+ // Get the google API key
+ $apiKey = $site->googleApi;
+
+ if ( ! empty($apiKey))
+ {
+ return sprintf($urls[$service], $apiKey);
+ }
+ }
+
+}
diff --git a/app/views/admin/dashboard.blade.php b/app/views/admin/dashboard.blade.php
index e24de9d..a49399e 100755
--- a/app/views/admin/dashboard.blade.php
+++ b/app/views/admin/dashboard.blade.php
@@ -22,8 +22,8 @@
<b>{{ Lang::get('admin.stickynotes_version') }}:</b>
{{ $sn_version }}
- <span class="ajax" data-realtime="false" data-onload="false" data-component="version">
- <span class="glyphicon glyphicon-refresh text-muted"></span>
+ <span data-toggle="ajax" data-onload="true" data-component="version">
+ <span class="glyphicon glyphicon-refresh"></span>
</span>
</div>
</div>
@@ -67,8 +67,8 @@
<div class="well well-sm well-white">
<b>{{ Lang::get('admin.system_load') }}:</b>
- <span class="ajax" data-realtime="true" data-onload="true" data-component="sysload">
- <span class="glyphicon glyphicon-refresh text-muted"></span>
+ <span data-toggle="ajax" data-realtime="true" data-onload="true" data-component="sysload">
+ <span class="glyphicon glyphicon-refresh"></span>
</span>
</div>
</div>
diff --git a/app/views/ajax/version/ok.blade.php b/app/views/ajax/version/ok.blade.php
new file mode 100644
index 0000000..a394282
--- /dev/null
+++ b/app/views/ajax/version/ok.blade.php
@@ -0,0 +1,4 @@
+<span class="glyphicon glyphicon-ok-sign text-success"
+ title="{{ Lang::get('ajax.version_ok') }}"
+ data-toggle="tooltip">
+</span>
diff --git a/app/views/ajax/version/old.blade.php b/app/views/ajax/version/old.blade.php
new file mode 100644
index 0000000..b6f19ee
--- /dev/null
+++ b/app/views/ajax/version/old.blade.php
@@ -0,0 +1,4 @@
+<span class="glyphicon glyphicon-exclamation-sign text-danger"
+ title="{{ Lang::get('ajax.version_old') }}"
+ data-toggle="tooltip">
+</span>
diff --git a/app/views/site/create.blade.php b/app/views/site/create.blade.php
index 3d574f3..04b3f1a 100755
--- a/app/views/site/create.blade.php
+++ b/app/views/site/create.blade.php
@@ -31,7 +31,7 @@
<div class="col-sm-4">
<div class="form-group">
{{
- Form::select('language', $languages, $paste->language ?: 'text', array(
+ Form::select('language', $languages, $paste->language ?: $language, array(
'class' => 'form-control',
$disabled => $disabled
))
diff --git a/app/views/site/show.blade.php b/app/views/site/show.blade.php
index 4b25221..9faca91 100755
--- a/app/views/site/show.blade.php
+++ b/app/views/site/show.blade.php
@@ -22,13 +22,17 @@
<div class="col-sm-7 text-right">
{{
link_to("#", Lang::get('show.short_url'), array(
- 'class' => 'btn btn-success'
+ 'class' => 'btn btn-success',
+ 'data-toggle' => 'ajax',
+ 'data-component' => 'shorten',
+ 'data-extra' => $paste->urlkey.($paste->private ? '/'.$paste->hash : ''),
))
}}
{{
link_to("#", Lang::get('show.wrap'), array(
- 'class' => 'btn btn-success'
+ 'class' => 'btn btn-success',
+ 'data-toggle' => 'wrap',
))
}}
diff --git a/public/assets/css/stickynotes.css b/public/assets/css/stickynotes.css
index dee3df3..b7f8e10 100755
--- a/public/assets/css/stickynotes.css
+++ b/public/assets/css/stickynotes.css
@@ -24,6 +24,7 @@ pre {
border-radius: 4px 4px 0 0;
margin: 0 0 -1px 0;
border-color: #e7e7e7;
+ overflow-x: auto;
}
pre ol {
margin: 0;
diff --git a/public/assets/js/stickynotes.js b/public/assets/js/stickynotes.js
index 905bfa7..b20c6bb 100644
--- a/public/assets/js/stickynotes.js
+++ b/public/assets/js/stickynotes.js
@@ -21,6 +21,12 @@ function stickyNotes()
{
// Initialize AJAX events
initAjax();
+
+ // Initialize code wrapping
+ initWrapToggle();
+
+ // Initialize the code editor
+ initEditor();
}
/**
@@ -38,44 +44,136 @@ function initAjax()
{
var count = 1;
- $('.ajax').each(function()
+ // Setup AJAX requests
+ $('[data-toggle="ajax"]').each(function()
{
- var id = 'ajax-' + count++;
-
- var realtime = $(this).attr('data-realtime') === 'true';
-
+ var id = 'stickynotes-' + count++;
var onload = $(this).attr('data-onload') === 'true';
-
+ var realtime = $(this).attr('data-realtime') === 'true';
var component = $(this).attr('data-component');
-
var extra = $(this).attr('data-extra');
// Set the id of this element
- $(this).attr('id', id);
+ $(this).attr('data-id', id);
- // ajaxUrl must be defined in your page template somewhere
- if (ajaxUrl !== undefined)
+ // ajaxUrl and component must be defined
+ if (ajaxUrl !== undefined && component !== undefined)
{
var getUrl = ajaxUrl + '/' + component + (extra !== undefined ? '/' + extra : '');
- var loop = setInterval(function()
+ var callback = function(e)
{
+ // Add the loading icon
+ $(this).html('<span class="glyphicon glyphicon-refresh"></span>');
+
+ // Send the AJAX request
$.ajax({
- url: getUrl,
- context: $('#' + id),
+ url: getUrl + '?key=' + Math.random(),
+ context: $('[data-id="' + id + '"]'),
success: function(response)
{
+ // Dump the HTML in the element
$(this).html(response);
+
+ // If response is link, set it as href as well
+ if (response.indexOf('http') === 0)
+ {
+ $(this).attr('href', response);
+ }
+
+ // Activate bootstrap components again
+ initBootstrap();
}
});
- if ( ! realtime || true)
+ if (e !== undefined)
+ {
+ e.preventDefault();
+ }
+ };
+
+ // For onload requests, execute the callback right away
+ // For the rest, bind it to the click event of the element
+ if (onload)
+ {
+ if (realtime)
+ {
+ setInterval(callback, 1000);
+ }
+ else
{
- clearInterval(loop);
+ setTimeout(callback);
}
- }, 1000);
+ }
+ else
+ {
+ $(this).click(callback);
+ }
+ }
+ });
+}
+
+/**
+ * Activates the code wrapping toggle function
+ *
+ * @return void
+ */
+function initWrapToggle()
+{
+ $('[data-toggle="wrap"]').click(function(e)
+ {
+ var isWrapped = $('pre div').css('white-space') != 'nowrap';
+ var newValue = isWrapped ? 'nowrap' : 'inherit';
+
+ $('pre div').css('white-space', newValue);
+
+ e.preventDefault();
+ });
+}
+
+/**
+ * Activates the paste editor
+ *
+ * @return void
+ */
+function initEditor()
+{
+ // Insert tab in the code box
+ $('[name="data"]').keydown(function (e)
+ {
+ if (e.keyCode == 9)
+ {
+ var myValue = "\t";
+ var startPos = this.selectionStart;
+ var endPos = this.selectionEnd;
+ var scrollTop = this.scrollTop;
+
+ this.value = this.value.substring(0, startPos) + myValue + \
this.value.substring(endPos,this.value.length); + this.focus();
+ this.selectionStart = startPos + myValue.length;
+ this.selectionEnd = startPos + myValue.length;
+ this.scrollTop = scrollTop;
+
+ e.preventDefault();
}
});
+
+ // Tick the private checkbox if password is entered
+ $('[name="password"]').keyup(function()
+ {
+ $('[name="private"]').attr('checked', $(this).val().length > 0);
+ });
+}
+
+/**
+ * Activates some bootstrap components
+ *
+ * @return void
+ */
+function initBootstrap()
+{
+ // Activate tooltips
+ $('[data-toggle="tooltip"]').tooltip();
}
/**
diff --git a/vendor/autoload.php b/vendor/autoload.php
index 421250e..ffeb911 100755
--- a/vendor/autoload.php
+++ b/vendor/autoload.php
@@ -4,4 +4,4 @@
require_once __DIR__ . '/composer' . '/autoload_real.php';
-return ComposerAutoloaderInitb4b70d7e6d995d7d7e5bb75e0884baaf::getLoader();
+return ComposerAutoloaderInitf1da2c49ffbe98583eb87187211c5db2::getLoader();
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
index 9be6147..d04647f 100755
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -8,11 +8,13 @@ $baseDir = dirname($vendorDir);
return array(
'API' => $baseDir . '/app/lib/API.php',
'AdminController' => $baseDir . '/app/controllers/AdminController.php',
+ 'AjaxController' => $baseDir . '/app/controllers/AjaxController.php',
'Antispam' => $baseDir . '/app/lib/Antispam.php',
'ApiController' => $baseDir . '/app/controllers/ApiController.php',
'BaseController' => $baseDir . '/app/controllers/BaseController.php',
'CreateController' => $baseDir . '/app/controllers/CreateController.php',
'DatabaseSeeder' => $baseDir . '/app/database/seeds/DatabaseSeeder.php',
+ 'GoogleSvc' => $baseDir . '/app/lib/GoogleSvc.php',
'Highlighter' => $baseDir . '/app/lib/Highlighter.php',
'IPBan' => $baseDir . '/app/models/IPBan.php',
'IlluminateQueueClosure' => $vendorDir . \
'/laravel/framework/src/Illuminate/Queue/IlluminateQueueClosure.php',
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
index 9800099..1d955e0 100755
--- a/vendor/composer/autoload_real.php
+++ b/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
// autoload_real.php generated by Composer
-class ComposerAutoloaderInitb4b70d7e6d995d7d7e5bb75e0884baaf
+class ComposerAutoloaderInitf1da2c49ffbe98583eb87187211c5db2
{
private static $loader;
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitb4b70d7e6d995d7d7e5bb75e0884baaf
return self::$loader;
}
- spl_autoload_register(array('ComposerAutoloaderInitb4b70d7e6d995d7d7e5bb75e0884baaf', \
'loadClassLoader'), true, true); + \
spl_autoload_register(array('ComposerAutoloaderInitf1da2c49ffbe98583eb87187211c5db2', 'loadClassLoader'), \
true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader();
- spl_autoload_unregister(array('ComposerAutoloaderInitb4b70d7e6d995d7d7e5bb75e0884baaf', \
'loadClassLoader')); + \
spl_autoload_unregister(array('ComposerAutoloaderInitf1da2c49ffbe98583eb87187211c5db2', \
'loadClassLoader'));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic