1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-29 09:31:50 +00:00

refactor build config

This commit is contained in:
Rokt33r
2015-06-21 02:40:06 +09:00
parent 9e53bec631
commit 25eccacb4c
81 changed files with 6418 additions and 450 deletions

13
src/browser/main/app.js Normal file
View File

@@ -0,0 +1,13 @@
/* global angular */
angular.module('codexen', [
'codexen.shared',
'ngSanitize',
'ui.select',
'ui.ace',
'ui.router',
'ui.bootstrap',
'satellizer',
'angular-md5',
'templates'])
.constant('appName', 'main')
angular.module('templates', [])

View File

@@ -0,0 +1,74 @@
/* global angular */
angular.module('codexen')
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.when('/auth', '/auth/register')
.when('/auth/', '/auth/register')
.otherwise('/')
$stateProvider
/* Auth */
.state('auth', {
url: '/auth',
views: {
'main-view': {
templateUrl: 'tpls/states/auth.tpl.html'
}
}
})
.state('auth.register', {
url: '/register',
templateUrl: 'tpls/states/auth.register.tpl.html',
controller: 'AuthRegisterController as vm'
})
.state('auth.signin', {
url: '/signin',
templateUrl: 'tpls/states/auth.signin.tpl.html',
controller: 'AuthSignInController as vm'
})
.state('settings', {
url: '/settings',
views: {
'main-view': {
templateUrl: 'tpls/states/settings.tpl.html',
controller: 'SettingsController as vm'
}
}
})
/* Snippets */
.state('snippets', {
url: '/snippets',
views: {
'main-view': {
templateUrl: 'tpls/states/snippets.list.tpl.html',
controller: 'SnippetsListController as vm'
}
},
resolve: {
mySnippets: function (Snippet) {
return Snippet.findMine().then(function (res) {
return res.data
})
}
}
})
.state('snippets.detail', {
url: '/:id',
templateUrl: 'tpls/states/snippets.detail.tpl.html',
controller: 'SnippetsDetailController as vm'
})
/* Home */
.state('home', {
url: '/',
views: {
'main-view': {
templateUrl: 'tpls/states/home.tpl.html',
controller: 'HomeController as vm'
}
}
})
})

View File

@@ -0,0 +1,3 @@
/* global angular */
angular.module('codexen')
.controller('AppController', function ($scope) {})

View File

@@ -0,0 +1,36 @@
/* global angular */
angular.module('codexen')
.controller('SideNavController', function ($auth, User, $rootScope, $scope) {
var vm = this
vm.isAuthenticated = $auth.isAuthenticated()
var reloadUser = function () {
if (vm.isAuthenticated) {
User.me().success(function (data) {
console.log('currentUser', data)
vm.currentUser = data
})
}
}
reloadUser()
vm.signOut = function () {
$auth.logout()
.then(function () {
console.log('Sign Out')
$rootScope.$broadcast('userSignOut')
})
}
$scope.$on('userSignIn', function () {
vm.isAuthenticated = true
reloadUser()
})
$scope.$on('userSignOut', function () {
vm.isAuthenticated = false
vm.currentUser = null
})
})

View File

@@ -0,0 +1,16 @@
/* global angular */
angular.module('codexen')
.controller('DeleteSnippetModalController', function ($modalInstance, Snippet, snippet) {
var vm = this
vm.submit = function () {
Snippet.delete(snippet.id)
.success(function (snippet) {
$modalInstance.close(snippet)
})
}
vm.cancel = function () {
$modalInstance.dismiss()
}
})

View File

@@ -0,0 +1,44 @@
/* global angular */
angular.module('codexen')
.controller('EditSnippetModalController', function ($modalInstance, aceModes, $log, Snippet, $rootScope, Tag, snippet) {
var vm = this
vm.aceModes = aceModes
vm.snippet = snippet
vm.submit = function () {
var params = {
description: vm.snippet.description,
callSign: vm.snippet.callSign,
mode: vm.snippet.mode == null ? null : vm.snippet.mode.toLowerCase(),
content: vm.snippet.content,
Tags: angular.isArray(vm.snippet.Tags) ? vm.snippet.Tags.map(function (tag) { return tag.name }) : []
}
Snippet.update(vm.snippet.id, params)
.success(function (data) {
console.log('updated res :', data)
$modalInstance.close(data)
})
}
// vm.tags = []
vm.tagCandidates = []
vm.refreshTagCandidates = function (tagName) {
if (tagName == null || tagName === '') return null
return Tag.findByName(tagName)
.success(function (data) {
console.log('tags fetched!!', data)
vm.tagCandidates = data
})
}
vm.transform = function (tagName) {
return {
id: 0,
name: tagName
}
}
vm.cancel = function () {
$modalInstance.dismiss()
}
})

View File

@@ -0,0 +1,43 @@
/* global angular */
angular.module('codexen')
.controller('NewSnippetModalController', function ($modalInstance, aceModes, $log, Snippet, $rootScope, Tag) {
var vm = this
vm.aceModes = aceModes
vm.submit = function () {
var params = {
description: vm.description,
callSign: vm.callSign,
mode: vm.mode == null ? null : vm.mode.toLowerCase(),
content: vm.content,
Tags: angular.isArray(vm.Tags) ? vm.Tags.map(function (tag) { return tag.name }) : []
}
Snippet.create(params)
.success(function (data) {
$modalInstance.close(data)
})
}
// vm.tags = []
vm.tagCandidates = []
vm.refreshTagCandidates = function (tagName) {
if (tagName == null || tagName === '') return null
return Tag.findByName(tagName)
.success(function (data) {
console.log('tags fetched!!', data)
vm.tagCandidates = data
})
}
vm.transform = function (tagName) {
return {
id: 0,
name: tagName
}
}
vm.cancel = function () {
$modalInstance.dismiss()
}
})

View File

@@ -0,0 +1,20 @@
/* global angular */
angular.module('codexen')
.controller('AuthRegisterController', function ($auth, $log, $state, $rootScope) {
var vm = this
vm.isEmpty = function (obj) {
for (var i in obj) if (obj.hasOwnProperty(i)) return false
return true
}
vm.signup = function () {
$auth.signup({
email: vm.email,
password: vm.password,
name: vm.name,
profileName: vm.profileName
}).then(function (data) {
$rootScope.$broadcast('userSignIn')
$state.go('home')
})
}
})

View File

@@ -0,0 +1,15 @@
/* global angular */
angular.module('codexen')
.controller('AuthSignInController', function ($auth, $rootScope) {
var vm = this
vm.signIn = function () {
$auth.login({
email: vm.email,
password: vm.password
}).then(function (data) {
console.log(data)
$rootScope.$broadcast('userSignIn')
})
}
})

View File

@@ -0,0 +1,3 @@
/* global angular */
angular.module('codexen')
.controller('HomeController', function ($auth, Snippet, $scope) {})

View File

@@ -0,0 +1,33 @@
/* global angular */
angular.module('codexen')
.controller('SettingsController', function (Settings) {
var vm = this
vm.changePassword = changePassword
vm.isSuccess = false
vm.isError = false
function changePassword () {
var params = {
password: vm.password,
newPassword: vm.newPassword
}
Settings.changePassword(params)
.success(function (data) {
resetInput()
vm.isSuccess = true
vm.isError = false
})
.error(function () {
resetInput()
vm.isError = true
vm.isSuccess = false
})
}
function resetInput () {
vm.password = ''
vm.newPassword = ''
}
})

View File

@@ -0,0 +1,31 @@
/* global angular */
angular.module('codexen')
.controller('SnippetsDetailController', function (Snippet, $state, $rootScope, $scope, Modal) {
var vm = this
vm.isLoaded = false
var snippetId = $state.params.id
Snippet.show(snippetId)
.success(function (data) {
vm.snippet = data
vm.isLoaded = true
})
$scope.$on('taggingRequested', function (e) {
e.stopPropagation()
e.preventDefault()
Modal.editSnippet(angular.copy(vm.snippet))
.result.then(function (snippet) {
$rootScope.$broadcast('snippetUpdated', snippet)
}, function () {
console.log('edit snippet modal dismissed')
})
})
$scope.$on('snippetUpdated', function (e, snippet) {
console.log('event received', snippet)
if (snippet.id === vm.snippet.id) vm.snippet = snippet
})
})

View File

@@ -0,0 +1,110 @@
/* global angular */
angular.module('codexen')
.controller('SnippetsListController', function ($auth, Snippet, $scope, $state, $scope, $filter, mySnippets, User) {
var vm = this
vm.isLoading = false
vm.snippetId = parseInt($state.params.id)
vm.snippets = mySnippets
vm.searchSnippets = searchSnippets
vm.searchSnippets()
vm.isAuthenticated = $auth.isAuthenticated()
var reloadUser = function () {
if (vm.isAuthenticated) {
User.me().success(function (data) {
vm.currentUser = data
})
}
}
reloadUser()
// TODO: add Navigation methods
// vm.nextSnippet()
// vm.priorSnippet()
// vm.firstSnippet()
// vm.lastSnippet()
// TODO: keyboard navigating UX
$scope.$on('$stateChangeSuccess', function (e, toState, toParams) {
if (!toState.name.match(/snippets/)) return null
vm.snippetId = parseInt(toParams.id)
if (!vm.snippetId && vm.filtered[0]) {
$state.go('snippets.detail', {id: vm.filtered[0].id})
}
})
$scope.$on('snippetUpdated', function (e, snippet) {
if (!mySnippets.some(function (_snippet, index) {
if (_snippet.id === snippet.id) {
mySnippets[index] = snippet
return true
}
return false
})) mySnippets.unshift(snippet)
searchSnippets()
vm.snippetId = snippet.id
$state.go('snippets.detail', {id: snippet.id})
})
$scope.$on('snippetDeleted', function () {
if ($state.is('snippets.detail')) {
var currentSnippetId = parseInt($state.params.id)
// Delete snippet from snippet list
for (var i = 0; i < vm.snippets.length; i++) {
if (vm.snippets[i].id === currentSnippetId) {
vm.snippets.splice(i, 1)
break
}
}
// Delete snippet from `filtered list`
// And redirect `next filtered snippet`
for (var i = 0; i < vm.filtered.length; i++) {
if (vm.filtered[i].id === currentSnippetId) {
if (vm.filtered[i+1] != null) $state.go('snippets.detail', {id: vm.filtered[i+1].id})
else if (vm.filtered[i-1] != null) $state.go('snippets.detail', {id: vm.filtered[i-1].id})
else $state.go('snippets')
vm.filtered.splice(i, 1)
break
}
}
}
})
$scope.$on('tagSelected', function (e, tag) {
e.stopPropagation()
$scope.$apply(function () {
vm.search = '#' + tag.name
searchSnippets()
})
})
function loadSnippets() {
if ($auth.isAuthenticated) {
Snippet.findMine()
.success(function (data) {
vm.snippets = data
})
} else {
vm.snippets = void 0
}
}
function searchSnippets() {
vm.filtered = $filter('searchSnippets')(mySnippets, vm.search)
if (vm.search && vm.filtered[0] && (!vm.snippetId || vm.snippetId !== vm.filtered[0].id)) {
$state.go('snippets.detail', {id: vm.filtered[0].id})
}
}
})

View File

@@ -0,0 +1,19 @@
/* global angular */
angular.module('codexen')
.directive('btnDeleteSnippet', function (Modal, $rootScope) {
return {
scope: {
snippet: '=btnDeleteSnippet'
},
link: function (scope, el) {
el.on('click', function () {
Modal.deleteSnippet(scope.snippet)
.result.then(function (snippet) {
$rootScope.$broadcast('snippetDeleted', snippet)
}, function () {
console.log('delete snippet modal dismissed')
})
})
}
}
})

View File

@@ -0,0 +1,19 @@
/* global angular */
angular.module('codexen')
.directive('btnEditSnippet', function (Modal, $rootScope) {
return {
scope: {
snippet: '=btnEditSnippet'
},
link: function (scope, el) {
el.on('click', function () {
Modal.editSnippet(angular.copy(scope.snippet))
.result.then(function (snippet) {
$rootScope.$broadcast('snippetUpdated', snippet)
}, function () {
console.log('edit snippet modal dismissed')
})
})
}
}
})

View File

@@ -0,0 +1,16 @@
/* global angular */
angular.module('codexen')
.directive('btnNewSnippet', function (Modal, $rootScope) {
return {
link: function (scope, el) {
el.on('click', function () {
Modal.newSnippet()
.result.then(function (snippet) {
$rootScope.$broadcast('snippetUpdated', snippet)
}, function () {
console.log('new snippet modal dismissed')
})
})
}
}
})

View File

@@ -0,0 +1,8 @@
/* global angular */
angular.module('codexen')
.directive('sideNav', function () {
return {
templateUrl: 'tpls/directives/side-nav.tpl.html',
controller: 'SideNavController as vm'
}
})

View File

@@ -0,0 +1,24 @@
/* global angular */
angular.module('codexen')
.directive('snippetItem', function (Modal, $rootScope) {
return {
restrict: 'A',
transclude: true,
template: '<div ng-transclude></div>',
scope: {
snippet: '=snippetItem'
},
link: function (scope, elem) {
scope.$on('taggingRequested', function (e) {
e.stopPropagation()
e.preventDefault()
Modal.editSnippet(angular.copy(scope.snippet))
.result.then(function (snippet) {
$rootScope.$broadcast('snippetUpdated', snippet)
}, function () {
console.log('edit snippet modal dismissed')
})
})
}
}
})

View File

@@ -0,0 +1,16 @@
/* global angular */
angular.module('codexen')
.directive('tagItem', function () {
return {
restrict: 'A',
template: '#<span ng-bind="tag.name"></span>',
scope: {
tag: '=tagItem'
},
link: function (scope, el) {
el.on('click', function () {
scope.$emit('tagSelected', scope.tag)
})
}
}
})

View File

@@ -0,0 +1,28 @@
/* global angular */
angular.module('codexen')
.directive('tagList', function () {
return {
restrict: 'A',
template: '<p class="tags">' +
'<i class="fa fa-tags"></i> ' +
'<a tag-item="tag" ng-repeat="tag in tags" href></a>' +
'<a ng-if="!tags.length" ng-click="requestTagging($event)" href> Not tagged yet</a>' +
'</p>',
scope: {
tags: '=tagList'
},
link: function (scope, el) {
el.ready(function () {
el.find('a').on('click', function (e) {
e.stopPropagation()
})
})
scope.requestTagging = function (e) {
e.preventDefault()
e.stopPropagation()
scope.$emit('taggingRequested')
}
}
}
})

View File

@@ -0,0 +1,7 @@
/* global angular moment */
angular.module('codexen')
.filter('fromNow', function () {
return function (input) {
return moment(input).fromNow()
}
})

View File

@@ -0,0 +1,17 @@
/* global angular */
angular.module('codexen')
.filter('searchSnippets', function ($filter) {
return function (input, needle) {
if (!angular.isString(needle) || !angular.isArray(input)) return angular.copy(input)
if (needle.match(/#(.+)|tag:(.+)/)) {
var name = needle.match(/#(.+)/) ? needle.match(/#(.+)/)[1] : needle.match(/tag:(.+)/)[1]
return input.filter(function (snippet) {
return snippet.Tags.some(function (tag) {
return tag.name.match(new RegExp('^'+name))
})
})
}
else return $filter('filter')(input, needle)
}
})

View File

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html ng-app="codexen">
<head>
<title>
CodeXen App
</title>
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<meta name="description" content="CodeXen - Short code storage service">
<title>Codexen!</title>
<link rel="stylesheet" href="../vendor/css/font-awesome.css" media="screen" title="no title" charset="utf-8">
<!-- inject:css -->
<link rel="stylesheet" href="styles/app.css">
<link rel="stylesheet" href="../shared/styles/bootstrap.css">
<!-- endinject -->
</head>
<body ng-controller="AppController as app">
<div side-nav id="side-view"></div>
<div ui-view name="main-view" id="main-view"></div>
<script src="../vendor/ace.js"></script>
<script src="../vendor/angular.js"></script>
<script src="../vendor/angular-sanitize.js"></script>
<script src="../vendor/angular-ui-router.js"></script>
<script src="../vendor/ui-bootstrap-tpls.js"></script>
<script src="../vendor/select.js"></script>
<script src="../vendor/satellizer.js"></script>
<script src="../vendor/angular-md5.js"></script>
<script src="../vendor/moment.js"></script>
<!-- inject:js -->
<script src="app.js"></script>
<script src="config/states.js"></script>
<script src="controllers/AppController.js"></script>
<script src="filters/from-now.js"></script>
<script src="filters/search-snippets.js"></script>
<script src="directives/btn-delete-snippet.js"></script>
<script src="directives/btn-edit-snippet.js"></script>
<script src="directives/btn-new-snippet.js"></script>
<script src="directives/side-nav.js"></script>
<script src="directives/snippet-item.js"></script>
<script src="directives/tag-item.js"></script>
<script src="directives/tag-list.js"></script>
<script src="services/Modal.js"></script>
<script src="services/Settings.js"></script>
<script src="services/Tag.js"></script>
<script src="services/User.js"></script>
<script src="controllers/directives/SideNavController.js"></script>
<script src="controllers/modals/DeleteSnippetModalController.js"></script>
<script src="controllers/modals/EditSnippetModalController.js"></script>
<script src="controllers/modals/NewSnippetModalController.js"></script>
<script src="controllers/states/AuthRegisterController.js"></script>
<script src="controllers/states/AuthSignInController.js"></script>
<script src="controllers/states/HomeController.js"></script>
<script src="controllers/states/SettingsController.js"></script>
<script src="controllers/states/SnippetsDetailController.js"></script>
<script src="controllers/states/SnippetsListController.js"></script>
<script src="../shared/shared.js"></script>
<script src="../shared/config/ace.js"></script>
<script src="../shared/config/env.js"></script>
<script src="../shared/config/satellizer.js"></script>
<script src="../shared/directives/ui-ace.js"></script>
<script src="../shared/services/Snippet.js"></script>
<!-- endinject -->
</body>
</html>

View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html ng-app="codexen">
<head>
<title>
CodeXen App
</title>
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<meta name="description" content="CodeXen - Short code storage service">
<title>Codexen!</title>
<link rel="stylesheet" href="../vendor/css/font-awesome.css" media="screen" title="no title" charset="utf-8">
<!-- inject:css -->
<!-- endinject -->
</head>
<body ng-controller="AppController as app">
<div side-nav id="side-view"></div>
<div ui-view name="main-view" id="main-view"></div>
<script src="../vendor/ace.js"></script>
<script src="../vendor/angular.js"></script>
<script src="../vendor/angular-sanitize.js"></script>
<script src="../vendor/angular-ui-router.js"></script>
<script src="../vendor/ui-bootstrap-tpls.js"></script>
<script src="../vendor/select.js"></script>
<script src="../vendor/satellizer.js"></script>
<script src="../vendor/angular-md5.js"></script>
<script src="../vendor/moment.js"></script>
<!-- inject:js -->
<!-- endinject -->
</body>
</html>

View File

@@ -0,0 +1,40 @@
/* global angular */
angular.module('codexen')
.factory('Modal', function ($modal) {
var newSnippet = function () {
return $modal.open({
templateUrl: 'tpls/modals/new-snippet-modal.tpl.html',
controller: 'NewSnippetModalController as vm'
})
}
var editSnippet = function (snippet) {
return $modal.open({
resolve: {
snippet: function () {
return snippet
}
},
templateUrl: 'tpls/modals/edit-snippet-modal.tpl.html',
controller: 'EditSnippetModalController as vm'
})
}
var deleteSnippet = function (snippet) {
return $modal.open({
resolve: {
snippet: function () {
return snippet
}
},
templateUrl: 'tpls/modals/delete-snippet-modal.tpl.html',
controller: 'DeleteSnippetModalController as vm'
})
}
return {
newSnippet: newSnippet,
editSnippet: editSnippet,
deleteSnippet: deleteSnippet
}
})

View File

@@ -0,0 +1,13 @@
/* global angular */
angular.module('codexen')
.factory('Settings', function ($http, apiUrl) {
var changePassword = function (params) {
var url = apiUrl + 'settings/change_password'
return $http.post(url, params)
}
return {
changePassword: changePassword
}
})

View File

@@ -0,0 +1,17 @@
/* global angular */
angular.module('codexen')
.factory('Tag', function ($http, apiUrl) {
var findByName = function (tagName) {
var url = apiUrl + 'tags/search'
return $http.get(url, {
params: {
name: tagName
}
})
}
return {
findByName: findByName
}
})

View File

@@ -0,0 +1,16 @@
/* global angular */
angular.module('codexen')
.factory('User', function ($http, apiUrl, $rootScope, $state) {
$rootScope.$on('userSignOut', function () {
$state.go('auth.signin')
})
var me = function () {
var url = apiUrl + 'auth/user'
return $http.get(url)
}
return {
me: me
}
})

View File

@@ -0,0 +1,378 @@
.new-snippet-modal .ace_editor {
height: 200px;
}
#side-view .nav-control-group {
margin: 0 5px;
}
#side-view ul.nav.nav-pills {
margin-top: 10px;
}
#side-view ul.nav.nav-pills li hr {
margin: 5px 0;
border-top: none;
border-bottom: solid 1px #001a20;
}
#side-view ul.nav.nav-pills li a {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
-webkit-transition: 0.2s;
transition: 0.2s;
}
#side-view ul.nav.nav-pills li.active > a,
#side-view ul.nav.nav-pills .nav-pills > li.active > a:hover,
#side-view ul.nav.nav-pills .nav-pills > li.active > a:focus {
background-color: #004b5f;
}
/*
* ui-select
* http://github.com/angular-ui/ui-select
* Version: 0.11.2 - 2015-03-17T04:08:46.478Z
* License: MIT
*/
.ui-select-highlight {
font-weight: bold;
}
.ui-select-offscreen {
clip: rect(0 0 0 0) !important;
width: 1px !important;
height: 1px !important;
border: 0 !important;
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
position: absolute !important;
outline: 0 !important;
left: 0px !important;
top: 0px !important;
}
.ng-dirty.ng-invalid > a.select2-choice {
border-color: #d44950;
}
.select2-result-single {
padding-left: 0;
}
.select2-locked > .select2-search-choice-close {
display: none;
}
.select-locked > .ui-select-match-close {
display: none;
}
body > .select2-container.open {
z-index: 9999;
}
.selectize-input.selectize-focus {
border-color: #007fbb !important;
}
.selectize-control > .selectize-input > input {
width: 100%;
}
.selectize-control > .selectize-dropdown {
width: 100%;
}
.ng-dirty.ng-invalid > div.selectize-input {
border-color: #d44950;
}
.btn-default-focus {
color: #333;
background-color: #ebebeb;
border-color: #adadad;
text-decoration: none;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 8px rgba(102,175,233,0.6);
}
.ui-select-bootstrap .ui-select-toggle {
position: relative;
border-radius: $input-border-radius;
}
.ui-select-bootstrap .ui-select-toggle .ui-select-placeholder {
color: #99b2b8;
}
.ui-select-bootstrap .ui-select-toggle > .caret {
position: absolute;
height: 10px;
top: 50%;
right: 10px;
margin-top: -2px;
}
.input-group > .ui-select-bootstrap.dropdown {
/* Instead of relative */
position: static;
}
.input-group > .ui-select-bootstrap > input.ui-select-search.form-control {
border-radius: $input-border-radius;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.ui-select-bootstrap > .ui-select-match > .btn {
/* Instead of center because of .btn */
text-align: left !important;
padding-right: 25px;
border-radius: $input-border-radius;
border: solid 1px #001a20;
}
.ui-select-bootstrap > .ui-select-match > .caret {
position: absolute;
top: 45%;
right: 15px;
}
.ui-select-bootstrap > .ui-select-choices {
width: 100%;
height: auto;
max-height: 200px;
overflow-x: hidden;
margin-top: -1px;
}
body > .ui-select-bootstrap.open {
z-index: 1000;
}
.ui-select-multiple.ui-select-bootstrap {
height: auto;
padding: 3px 3px 0 10px;
}
.ui-select-multiple.ui-select-bootstrap.open {
border-color: #52dcff;
outline: 0;
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 8px rgba(82,220,255,0.6);
}
.ui-select-multiple.ui-select-bootstrap input.ui-select-search {
background-color: transparent !important;
border: none;
outline: none;
height: 1.666666em;
margin-bottom: 3px;
}
.ui-select-multiple.ui-select-bootstrap .ui-select-match .close {
font-size: 1.6em;
line-height: 0.75;
}
.ui-select-multiple.ui-select-bootstrap .ui-select-match-item {
outline: 0;
margin: 0 3px 3px 0;
}
.ui-select-multiple .ui-select-match-item {
position: relative;
}
.ui-select-multiple .ui-select-match-item.dropping-before:before {
content: "";
position: absolute;
top: 0;
right: 100%;
height: 100%;
margin-right: 2px;
border-left: 1px solid #428bca;
}
.ui-select-multiple .ui-select-match-item.dropping-after:after {
content: "";
position: absolute;
top: 0;
left: 100%;
height: 100%;
margin-left: 2px;
border-right: 1px solid #428bca;
}
.ui-select-bootstrap .ui-select-choices-row>a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: 400;
line-height: 1.42857143;
color: #99b2b8;
white-space: nowrap;
}
.ui-select-bootstrap .ui-select-choices-row>a:hover,
.ui-select-bootstrap .ui-select-choices-row>a:focus {
text-decoration: none;
color: #fff;
background-color: #004b5f;
}
.ui-select-bootstrap .ui-select-choices-row.active>a {
color: #fff;
text-decoration: none;
outline: 0;
background-color: #004b5f;
}
.ui-select-bootstrap .ui-select-choices-row.disabled>a,
.ui-select-bootstrap .ui-select-choices-row.active.disabled>a {
color: #777;
cursor: not-allowed;
background-color: #fff;
}
.ui-select-match.ng-hide-add,
.ui-select-search.ng-hide-add {
display: none !important;
}
.ui-select-bootstrap.ng-dirty.ng-invalid > button.btn.ui-select-match {
border-color: #d44950;
}
.auth-state .panel {
margin-top: 50px;
}
.auth-state h1 {
margin: 15px 0;
}
.auth-state .auth-control {
margin: 10px 0;
}
.home-state {
padding: 10px;
}
.settings-state .panel {
margin-top: 15px;
}
.settings-state h1 {
margin: 30px 0;
}
.settings-state .section h4 {
margin-bottom: 15px;
}
.snippets-list-state {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.snippets-list-state .left-pane {
border-right: 1px solid #001a20;
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 275px;
overflow: hidden;
}
.snippets-list-state .left-pane .snippet-search {
position: absolute;
top: 0;
height: 50px;
left: 0;
right: 0;
border-right: 1px solid #001a20;
padding: 7px 5px;
}
.snippets-list-state .left-pane .snippet-list {
position: absolute;
top: 50px;
bottom: 0;
left: 0;
right: 0;
overflow-x: hidden;
overflow-y: auto;
list-style: none;
padding: 0;
}
.snippets-list-state .left-pane .snippet-list li {
cursor: pointer;
padding: 5px;
border-right: 1px solid #001a20;
border-bottom: 1px solid #001a20;
}
.snippets-list-state .left-pane .snippet-list li:nth-child(even) {
background-color: #002b36;
}
.snippets-list-state .left-pane .snippet-list li:nth-child(odd) {
background-color: #00323f;
}
.snippets-list-state .left-pane .snippet-list li h4 {
margin: 0;
}
.snippets-list-state .left-pane .snippet-list li:hover {
background-color: #004b5f;
}
.snippets-list-state .left-pane .snippet-list li p {
margin: 0;
}
.snippets-list-state .left-pane .snippet-list li p.call-sign {
font-size: 0.8em;
}
.snippets-list-state .left-pane .snippet-list li p.created-at {
font-size: 0.8em;
opacity: 0.8;
}
.snippets-list-state .left-pane .snippet-list li.active {
color: #fff;
background-color: #088cff;
}
.snippets-list-state .left-pane .snippet-list li.active a {
color: #fff;
}
.snippets-list-state .right-pane {
position: absolute;
top: 0;
bottom: 0;
left: 275px;
right: 0;
overflow-x: hidden;
overflow-y: auto;
background-color: #00323f;
}
.snippets-detail-state {
position: absolute;
top: 0;
width: 100%;
bottom: 0;
overflow: hidden;
}
.snippets-detail-state .detail-header {
position: absolute;
top: 0;
width: 100%;
background-color: #003d4d;
padding: 5px 10px;
height: 50px;
border-bottom: solid 1px #001a20;
}
.snippets-detail-state .detail-header .detail-header-title {
color: #d5dfe2;
line-height: 40px;
font-size: 1.2em;
}
.snippets-detail-state .detail-header .detail-header-title small {
font-size: 0.6em;
color: #99b2b8;
}
.snippets-detail-state .detail-header .detail-header-control {
padding: 3px;
}
.snippets-detail-state .detail-body {
position: absolute;
top: 50px;
width: 100%;
bottom: 0;
padding: 5px 10px;
overflow-y: auto;
}
.snippets-detail-state .detail-body .ace_editor {
min-height: 300px;
border: solid 1px $border-color;
border-radius: 5px;
margin-bottom: 5px;
}
.tags {
word-break: break-all;
}
.tags a {
margin: 0 2px;
}
#side-view {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 200px;
background-color: #002b36;
border-right: solid 2px #004b5f;
box-sizing: border-box;
padding: 10px 0 10px 10px;
}
#main-view {
position: absolute;
top: 0;
bottom: 0;
left: 200px;
right: 0;
overflow-x: hidden;
overflow-y: auto;
background-color: $bgDarker;
}

View File

@@ -0,0 +1,27 @@
@import '../../shared/styles/_vars'
@import '../../shared/styles/mixins/*'
@import 'modals/*'
@import 'directives/*'
@import 'states/*'
#side-view
position:absolute
top: 0
bottom: 0
left: 0
width: 200px
background-color: $baseBackgroundColor
border-right solid 2px $backgroundColorSelected
box-sizing: border-box
padding: 10px 0 10px 10px
#main-view
position:absolute
top: 0
bottom: 0
left: 200px
right: 0
overflow-x: hidden
overflow-y: auto
background-color $bgDarker

View File

@@ -0,0 +1,17 @@
#side-view
.nav-control-group
margin 0 5px
ul.nav.nav-pills
margin-top 10px
li hr
margin: 5px 0
border-top none
border-bottom solid 1px $baseBorderColor
li a
border-top-right-radius 0
border-bottom-right-radius 0
transition 0.2s
li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus{
background-color: $backgroundColorSelected
}

View File

@@ -0,0 +1,232 @@
/*!
* ui-select
* http://github.com/angular-ui/ui-select
* Version: 0.11.2 - 2015-03-17T04:08:46.478Z
* License: MIT
*/
/* Style when highlighting a search. */
.ui-select-highlight
font-weight: bold
.ui-select-offscreen
clip: rect(0 0 0 0) !important
width: 1px !important
height: 1px !important
border: 0 !important
margin: 0 !important
padding: 0 !important
overflow: hidden !important
position: absolute !important
outline: 0 !important
left: 0px !important
top: 0px !important
/* Select2 theme */
/* Mark invalid Select2 */
.ng-dirty.ng-invalid > a.select2-choice
border-color: #D44950
.select2-result-single
padding-left: 0
.select2-locked > .select2-search-choice-close
display:none
.select-locked > .ui-select-match-close
display:none
body > .select2-container.open
z-index: 9999 /* The z-index Select2 applies to the select2-drop */
/* Selectize theme */
/* Helper class to show styles when focus */
.selectize-input.selectize-focus
border-color: #007FBB !important
/* Fix input width for Selectize theme */
.selectize-control > .selectize-input > input
width: 100%
/* Fix dropdown width for Selectize theme */
.selectize-control > .selectize-dropdown
width: 100%
/* Mark invalid Selectize */
.ng-dirty.ng-invalid > div.selectize-input
border-color: #D44950
/* Bootstrap theme */
/* Helper class to show styles when focus */
.btn-default-focus
color: #333
background-color: #EBEBEB
border-color: #ADADAD
text-decoration: none
outline: 5px auto -webkit-focus-ring-color
outline-offset: -2px
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6)
.ui-select-bootstrap .ui-select-toggle
position: relative
border-radius $input-border-radius
.ui-select-placeholder
color $textColor
.ui-select-bootstrap .ui-select-toggle > .caret
position: absolute
height: 10px
top: 50%
right: 10px
margin-top: -2px
/* Fix Bootstrap dropdown position when inside a input-group */
.input-group > .ui-select-bootstrap.dropdown
/* Instead of relative */
position: static
.input-group > .ui-select-bootstrap > input.ui-select-search.form-control
border-radius: $input-border-radius
border-top-right-radius: 0
border-bottom-right-radius: 0
.ui-select-bootstrap > .ui-select-match > .btn
/* Instead of center because of .btn */
text-align: left !important
padding-right: 25px
border-radius $input-border-radius
border solid 1px $input-border
.ui-select-bootstrap > .ui-select-match > .caret
position: absolute
top: 45%
right: 15px
/* See Scrollable Menu with Bootstrap 3 http://stackoverflow.com/questions/19227496 */
.ui-select-bootstrap > .ui-select-choices
width: 100%
height: auto
max-height: 200px
overflow-x: hidden
margin-top: -1px
body > .ui-select-bootstrap.open
z-index: 1000 /* Standard Bootstrap dropdown z-index */
.ui-select-multiple.ui-select-bootstrap
height: auto
padding: 3px 3px 0 10px
.ui-select-multiple.ui-select-bootstrap.open
border-color $input-border-focus
outline 0
box-shadow inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(red($input-border-focus), green($input-border-focus), blue($input-border-focus), .6)
.ui-select-multiple.ui-select-bootstrap input.ui-select-search
background-color: transparent !important /* To prevent double background when disabled */
border: none
outline: none
height: 1.666666em
margin-bottom: 3px
.ui-select-multiple.ui-select-bootstrap .ui-select-match .close
font-size: 1.6em
line-height: 0.75
.ui-select-multiple.ui-select-bootstrap .ui-select-match-item
outline: 0
margin: 0 3px 3px 0
.ui-select-multiple .ui-select-match-item
position: relative
.ui-select-multiple .ui-select-match-item.dropping-before:before
content: ""
position: absolute
top: 0
right: 100%
height: 100%
margin-right: 2px
border-left: 1px solid #428bca
.ui-select-multiple .ui-select-match-item.dropping-after:after
content: ""
position: absolute
top: 0
left: 100%
height: 100%
margin-left: 2px
border-right: 1px solid #428bca
.ui-select-bootstrap .ui-select-choices-row>a
display: block
padding: 3px 20px
clear: both
font-weight: 400
line-height: 1.42857143
color: $dropdown-link-color
white-space: nowrap
.ui-select-bootstrap .ui-select-choices-row>a:hover, .ui-select-bootstrap .ui-select-choices-row>a:focus
text-decoration: none
color: $dropdown-link-hover-color
background-color: $dropdown-link-hover-bg
.ui-select-bootstrap .ui-select-choices-row.active>a
color: $dropdown-link-hover-color
text-decoration: none
outline: 0
background-color: $dropdown-link-hover-bg
.ui-select-bootstrap .ui-select-choices-row.disabled>a,
.ui-select-bootstrap .ui-select-choices-row.active.disabled>a
color: #777
cursor: not-allowed
background-color: #fff
/* fix hide/show angular animation */
.ui-select-match.ng-hide-add,
.ui-select-search.ng-hide-add
display: none !important
/* Mark invalid Bootstrap */
.ui-select-bootstrap.ng-dirty.ng-invalid > button.btn.ui-select-match
border-color: #D44950

View File

@@ -0,0 +1,4 @@
.new-snippet-modal
.ace_editor
height: 200px

View File

@@ -0,0 +1,7 @@
.auth-state
.panel
margin-top 50px
h1
margin 15px 0
.auth-control
margin 10px 0

View File

@@ -0,0 +1,2 @@
.home-state
padding 10px

View File

@@ -0,0 +1,8 @@
.settings-state
.panel
margin-top 15px
h1
margin 30px 0
.section
h4
margin-bottom 15px

View File

@@ -0,0 +1,132 @@
$left-pane-width= 275px
$pane-border-color= $border-color
$snippet-list-border-color= $border-color
$snippet-list-item-hover-bg= #EEE
$snippet-list-active-color= white
$snippet-list-active-bg= $brand-primary
.snippets-list-state
position: absolute
top:0
left:0
right:0
bottom:0
.left-pane
border-right 1px solid $baseBorderColor
position: absolute
top: 0
bottom: 0
left: 0
width: $left-pane-width
overflow:hidden
.snippet-search
position: absolute
top: 0
height: 50px
left: 0
right: 0
border-right 1px solid $baseBorderColor
padding: 7px 5px
.snippet-list
position: absolute
top: 50px
bottom: 0
left: 0
right: 0
overflow-x: hidden
overflow-y: auto
list-style: none
padding: 0
li
cursor: pointer
padding: 5px
border-right 1px solid $baseBorderColor
border-bottom 1px solid $baseBorderColor
&:nth-child(even)
background-color $baseBackgroundColor
&:nth-child(odd)
background-color lighten($baseBackgroundColor, 2%)
h4
margin: 0
&:hover
background-color: $backgroundColorSelected
p
margin:0
p.call-sign
font-size:0.8em
p.created-at
font-size:0.8em
opacity: 0.8
&.active
color: $snippet-list-active-color
background-color: $snippet-list-active-bg
a
color: white
.right-pane
position: absolute
top: 0
bottom: 0
left: $left-pane-width
right: 0
overflow-x: hidden
overflow-y: auto
background-color lighten($baseBackgroundColor, 2%)
.snippets-detail-state
position absolute
top 0
width 100%
bottom 0
overflow hidden
.detail-header
position absolute
top 0
width 100%
background-color lighten($baseBackgroundColor, 5%)
padding 5px 10px
height 50px
border-bottom solid 1px $baseBorderColor
.detail-header-title
color $textColorHighlight
line-height 40px
font-size 1.2em
small
font-size: 0.6em
color $textColor
.detail-header-control
padding 3px
.detail-body
position absolute
top 50px
width 100%
bottom 0
padding 5px 10px
overflow-y auto
.ace_editor
min-height 300px
border solid 1px $border-color
border-radius 5px
margin-bottom 5px
.tags
word-break: break-all
a
margin: 0 2px

View File

@@ -0,0 +1,35 @@
<div class="current-user">
<div ng-if="vm.currentUser">
<img width="30" class="img-circle" ng-src="http://www.gravatar.com/avatar/{{ vm.currentUser.email | gravatar }}">
<a href ng-bind="vm.currentUser.name"></a>
<span class="nav-control-group pull-right">
<a ui-sref="settings" class="btn btn-sm btn-default" ui-sref-active="active"}"><i class="fa fa-gears fa-fw"></i></a>
<a href class="btn btn-sm btn-default" ng-click="vm.signOut()"><i class="fa fa-sign-out fa-fw"></i></a>
</span>
</div>
<div ng-if="!vm.currentUser">
<span>Guest</span>
<span class="nav-control-group pull-right">
<a class="btn btn-sm btn-default" ui-sref="auth.register"><i class="fa fa-user-plus fa-fw"></i></a>
<a class="btn btn-sm btn-default" ui-sref="auth.signin"><i class="fa fa-sign-in fa-fw"></i></a>
</span>
</div>
</div>
<ul class="nav nav-pills nav-stacked">
<li>
<a btn-new-snippet href="#"><i class="fa fa-plus-square-o"></i> New Snippet</a>
</li>
<li class="divider"><hr></li>
<li>
</li>
<li ui-sref-active="active">
<a ui-sref="home"><i class="fa fa-home"></i> Home</a>
</li>
<li ui-sref-active="active">
<a ui-sref="snippets"><i class="fa fa-code"></i> Snippets</a>
</li>
</ul>

View File

@@ -0,0 +1,16 @@
<div class="new-snippet-modal">
<div class="modal-header">
<h4>Delete Snippet</h4>
</div>
<div class="modal-body">
<p>
Are you sure to delete it?
</p>
</div>
<div class="modal-footer">
<button ng-click="vm.submit()" type="button" name="button" class="btn btn-danger">Delete It</button>
<button ng-click="vm.cancel()" type="button" name="button" class="btn btn-default">Cancel</button>
</div>
</div>

View File

@@ -0,0 +1,49 @@
<div class="new-snippet-modal">
<div class="modal-header">
<h4>Edit Snippet</h4>
</div>
<div class="modal-body">
<div class="form-group">
<textarea ng-model="vm.snippet.description" name="description" class="form-control" placeholder="Description..."></textarea>
</div>
<div class="form-group">
<input ng-model="vm.snippet.callSign" type="text" name="callSign" class="inline-form-control" placeholder="Callsign">
<ui-select ng-model="vm.snippet.mode" style="display: inline-block;" theme="bootstrap">
<ui-select-match placeholder="Select Type">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="mode in vm.aceModes | filter:$select.search">
<div ng-bind-html="mode | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
<div class="form-group">
<div
ui-ace="{
mode: vm.snippet.mode.toLowerCase(),
theme:'solarized_dark',
useWrapMode : true
}"
ng-model="vm.snippet.content"
></div>
</div>
<div class="form-group">
<ui-select multiple tagging="vm.transform" tagging-tokens="SPACE|,|/" ng-model="vm.snippet.Tags" theme="bootstrap">
<ui-select-match placeholder="Tags...">{{$item.name}}</ui-select-match>
<ui-select-choices repeat="tag in vm.tagCandidates" refresh="vm.refreshTagCandidates($select.search)"
refresh-delay="200">
<div><span ng-bind-html="tag.name | highlight: $select.search"></span><span ng-if="tag.isTag">(new)</span></div>
</ui-select-choices>
</ui-select>
</div>
</div>
<div class="modal-footer">
<button ng-click="vm.submit()" type="button" name="button" class="btn btn-primary">Submit</button>
<button ng-click="vm.cancel()" type="button" name="button" class="btn btn-default">Cancel</button>
</div>
</div>

View File

@@ -0,0 +1,49 @@
<div class="new-snippet-modal">
<div class="modal-header">
<h4>New Snippet</h4>
</div>
<div class="modal-body">
<div class="form-group">
<textarea ng-model="vm.description" name="description" class="form-control" placeholder="Description..."></textarea>
</div>
<div class="form-group">
<input ng-model="vm.callSign" type="text" name="callSign" class="inline-form-control" placeholder="Callsign">
<ui-select ng-model="vm.mode" style="display: inline-block;" on-select="vm.log(vm.mode.name.toLowerCase())" theme="bootstrap">
<ui-select-match placeholder="Select Type">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="mode in vm.aceModes | filter: $select.search">
<div ng-bind="::mode"></div>
</ui-select-choices>
</ui-select>
</div>
<div class="form-group">
<div
ui-ace="{
mode: vm.mode.toLowerCase(),
theme:'solarized_dark',
useWrapMode : true
}"
ng-model="vm.content"
></div>
</div>
<div class="form-group">
<ui-select multiple tagging="vm.transform" tagging-tokens="SPACE|,|/" ng-model="vm.Tags" theme="bootstrap">
<ui-select-match placeholder="Tags...">{{$item.name}}</ui-select-match>
<ui-select-choices repeat="tag in vm.tagCandidates" refresh="vm.refreshTagCandidates($select.search)"
refresh-delay="100">
<div><span ng-bind-html="tag.name | highlight: $select.search"></span><span ng-if="tag.isTag">(new)</span></div>
</ui-select-choices>
</ui-select>
</div>
</div>
<div class="modal-footer">
<button ng-click="vm.submit()" type="button" name="button" class="btn btn-primary">Submit</button>
<button ng-click="vm.cancel()" type="button" name="button" class="btn btn-default">Cancel</button>
</div>
</div>

View File

@@ -0,0 +1,54 @@
<form novalidate name="registerForm" ng-submit="registerForm.$valid?vm.signup():null">
<!-- Email -->
<div class="form-group">
<label for="email">E-mail</label>
<input ng-model="vm.email" type="email" id="email" name="email" class="form-control" placeholder="E-mail" required>
<div class="alert alert-danger" ng-if="registerForm.$submitted && !vm.isEmpty(registerForm.email.$error)">
<div ng-show="registerForm.email.$error.required">No E-mail given.</div>
<div ng-show="registerForm.email.$error.email">Invalid Address.</div>
</div>
</div>
<!-- Password -->
<div class="form-group">
<label for="password">Password</label>
<input ng-model="vm.password" type="password" id="password" name="password" class="form-control" placeholder="Password" required>
<div class="alert alert-danger" ng-if="registerForm.$submitted && !vm.isEmpty(registerForm.password.$error)">
<div ng-show="registerForm.password.$error.required">No password given.</div>
</div>
</div>
<hr>
<!-- Username -->
<div class="form-group">
<label for="name">Username</label>
<input ng-model="vm.name" ng-pattern="'^[A-Za-z0-9\-\_]+$'" type="text" id="name" name="name" class="form-control" required>
<div class="alert alert-danger" ng-if="registerForm.$submitted && !vm.isEmpty(registerForm.name.$error)">
<div ng-show="registerForm.name.$error.required">No Username given.</div>
<div ng-show="registerForm.name.$error.pattern">Username should be ^[A-Za-z0-9\-\_]+$ (only alphanumeric, hyphen, underscore characters)</div>
</div>
</div>
<!-- Profile name -->
<div class="form-group">
<label for="profileName">Profile name</label>
<input ng-model="vm.profileName" type="text" name="profileName" class="form-control" required>
<div class="alert alert-danger" ng-if="registerForm.$submitted && !vm.isEmpty(registerForm.profileName.$error)">
<div ng-show="registerForm.profileName.$error.required">No Profile name given.</div>
</div>
</div>
<div class="form-group">
<button ng-class="{'btn-danger':registerForm.$invalid, 'btn-primary':registerForm.$valid}" type="submit" class="btn form-control">Register</button>
</div>
</form>

View File

@@ -0,0 +1,15 @@
<form ng-submit="vm.signIn()">
<div class="form-group">
<label for="email">E-mail</label>
<input ng-model="vm.email" type="text" id="email" name="name" class="form-control" placeholder="E-mail">
</div>
<div class="form-group">
<label for="password">Password</label>
<input ng-model="vm.password" type="password" id="password" name="name" class="form-control" placeholder="Password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary form-control">Sign In</button>
</div>
</form>

View File

@@ -0,0 +1,19 @@
<div class="auth-state container-fluid">
<div class="row">
<div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2 col-lg-6 col-lg-offset-3 panel panel-default">
<div class="text-center">
<h1>Authentication</h1>
<div class="auth-control">
<a class="btn btn-default" ui-sref-active="active" ui-sref="auth.register"><i class="fa fa-user-plus fa-fw"></i> Register</a> or <a class="btn btn-default" ui-sref-active="active" ui-sref="auth.signin"><i class="fa fa-sign-in fa-fw"></i> Sign In</a>
</div>
</div>
<ui-view></ui-view>
</div>
</div>
</div>

View File

@@ -0,0 +1,10 @@
<div class="home-state">
<h1 class="jumbotron">Codexen App <small>v0.1</small></h1>
<p>
App for Code snippets<br>
</p>
<p>
© 2015 MAISIN&CO.,Inc.
</p>
</div>

View File

@@ -0,0 +1,33 @@
<div class="settings-state container-fluid">
<div class="row">
<div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2 col-lg-6 col-lg-offset-3 panel panel-default">
<h1><i class="fa fa-gears"></i> Settings</h1>
<p>
Some settings...
</p>
<hr>
<div class="section">
<h4>Change Password</h4>
<form ng-submit="vm.changePassword()">
<alert type="success" ng-show="vm.isSuccess" close="vm.isSuccess=false">
Successfully changed!!
</alert>
<alert type="danger" ng-show="vm.isError" close="vm.isError=false">
Request failed!!
</alert>
<div class="form-group">
<label for="password">Current Password</label>
<input ng-model="vm.password" class="form-control" type="password" name="password" placeholder="Current Password">
</div>
<div class="form-group">
<label for="newPassword"> New Password</label>
<input ng-model="vm.newPassword" class="form-control" type="password" name="newPassword" placeholder="New Password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary form-control">Change Password</button>
</div>
</form>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,41 @@
<div class="snippets-detail-state">
<div class="detail-header">
<span class="detail-header-title">
<small>callsign</small>
<span ng-bind="vm.snippet.callSign"></span>
<small><span ng-bind="vm.snippet.updatedAt|fromNow"></span> <i class="fa fa-clock-o"></i></small>
</span>
<span class="detail-header-control pull-right">
<!-- <button type="button" name="button" class="btn btn-default"><i class="fa fa-share"></i></button> -->
<button btn-edit-snippet="vm.snippet" type="button" name="button" class="btn btn-default"><i class="fa fa-edit"></i></button>
<button btn-delete-snippet="vm.snippet" type="button" name="button" class="btn btn-danger"><i class="fa fa-trash"></i></button>
</span>
</div>
<div class="detail-body">
<div ng-if="!vm.isLoaded" class="">
Loadding
</div>
<div ng-if="vm.isLoaded" class="">
<p ng-bind="vm.snippet.description"></p>
<div tag-list="vm.snippet.Tags"></div>
<div ui-ace="{
showGutter: false,
useWrapMode : true,
mode:vm.snippet.mode.toLowerCase(),
maxLines: -1,
theme:'solarized_dark',
rendererOptions: {
maxLinks: Infinity
}
}"
readonly
ng-model="vm.snippet.content"></div>
</div>
</div>
</div>

View File

@@ -0,0 +1,57 @@
<div class="snippets-list-state">
<div class="left-pane">
<div class="snippet-search">
<input ng-model="vm.search" ng-change="vm.searchSnippets()" type="text" name="name" class="form-control" placeholder="Search ..." autocomplete="off">
</div>
<ul class="snippet-list">
<li ng-if="vm.isLoading" class="message-item">
<h4>
Loading
</h4>
</li>
<li ng-if="!vm.isLoading && vm.snippets==0 && !vm.isGuest" class="message-item">
<h4>
Empty List
</h4>
<button btn-new-snippet class="btn btn-default"><i class="fa fa-plus-square-o"></i> New Snippet</button>
</li>
<li ng-if="!vm.isLoading && vm.isGuest" class="message-item">
<h4>
Sign In to access
</h4>
<a ui-sref="auth.signin" class="btn btn-default"><i class="fa fa-signin"></i> Sign In</a>
</li>
<li snippet-item="snippet" ng-repeat="snippet in vm.filtered" ui-sref="snippets.detail({id:snippet.id})" ng-class="{active:vm.snippetId===snippet.id}">
<div class="media">
<div class="media-left">
<img width="25" height="25" class="img-circle" ng-src="http://www.gravatar.com/avatar/{{ vm.currentUser.email | gravatar }}" alt="" />
</div>
<div class="media-body">
<p ng-bind="snippet.callSign" class="call-sign">
</p>
<p ng-bind="snippet.description">
</p>
<p class="created-at">
<span ng-bind="snippet.updatedAt|fromNow"></span>
</p>
</div>
</div>
<div tag-list="snippet.Tags"></div>
</li>
</ul>
</div>
<div class="right-pane">
<div ng-if="'snippets'|isState">
No snippet selected.
</div>
<div ui-view></div>
</div>
</div>