diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js
index 109b5e2..9425ee9 100644
--- a/config/webpack.config.dev.js
+++ b/config/webpack.config.dev.js
@@ -10,7 +10,6 @@ var getClientEnvironment = require('./env');
var paths = require('./paths');
-
// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
var publicPath = '/';
@@ -75,10 +74,11 @@ module.exports = {
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
extensions: ['.js', '.json', '.jsx', ''],
+ modulesDirectories: [ 'src-react', 'node_modules' ],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
- 'react-native': 'react-native-web'
+ 'react-native': 'react-native-web',
}
},
@@ -111,6 +111,7 @@ module.exports = {
// Webpack 2 fixes this, but for now we include this hack.
// https://github.com/facebookincubator/create-react-app/issues/1713
/\.(js|jsx)(\?.*)?$/,
+ /\.scss$/,
/\.css$/,
/\.json$/,
/\.svg$/
@@ -143,6 +144,10 @@ module.exports = {
test: /\.css$/,
loader: 'style!css?importLoaders=1!postcss'
},
+ {
+ test: /\.scss$/,
+ loader: 'style!css!sass'
+ },
// JSON is not enabled by default in Webpack but both Node and Browserify
// allow it implicitly so we also enable it.
{
diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js
index 74a54b6..54398da 100644
--- a/config/webpack.config.prod.js
+++ b/config/webpack.config.prod.js
@@ -79,10 +79,11 @@ module.exports = {
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
extensions: ['.js', '.json', '.jsx', ''],
+ modulesDirectories: [ 'src-react', 'node_modules' ],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
- 'react-native': 'react-native-web'
+ 'react-native': 'react-native-web',
}
},
diff --git a/package.json b/package.json
index 0443646..8b439c2 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"bluebird": "~3.5.0",
"blueimp-md5": "~2.7.0",
"body-parser": "~1.17.1",
+ "bootstrap-sass": "^3.3.7",
"color": "~1.0.3",
"cookie-parser": "~1.4.3",
"crossroads": "~0.12.2",
@@ -55,6 +56,10 @@
"passport-local": "~1.0.0",
"raven": "~1.2.1",
"rc": "~1.2.1",
+ "react": "^15.5.4",
+ "react-dom": "^15.5.4",
+ "react-redux": "^5.0.4",
+ "redux": "^3.6.0",
"rimraf": "~2.6.1",
"semver": "~5.3.0",
"serve-static": "~1.12.2",
@@ -64,11 +69,7 @@
"superagent": "^0.21.0",
"temp": "~0.8.3",
"winston": "~2.3.1",
- "yargs": "~8.0.0-candidate.0",
- "react": "^15.5.4",
- "react-dom": "^15.5.4",
- "react-redux": "^5.0.4",
- "redux": "^3.6.0"
+ "yargs": "~8.0.0-candidate.0"
},
"devDependencies": {
"ansi-color": "~0.2.1",
@@ -122,11 +123,13 @@
"jest": "18.1.0",
"json-loader": "0.5.4",
"mocha": "~3.3.0",
+ "node-sass": "^4.5.3",
"object-assign": "4.1.1",
"phantomjs-prebuilt": "~2.1.14",
"postcss-loader": "1.2.2",
"promise": "7.1.1",
"react-dev-utils": "^0.5.2",
+ "sass-loader": "^6.0.5",
"style-loader": "0.13.1",
"supertest": "~3.0.0",
"url-loader": "0.5.7",
diff --git a/src-react/containers/path.js b/src-react/containers/path.js
index cb2c1b0..499d4e9 100644
--- a/src-react/containers/path.js
+++ b/src-react/containers/path.js
@@ -1,6 +1,8 @@
import React, { Component } from 'react';
import { connect } from 'react-redux'
+import 'styles/styles.scss';
+
@connect(state => { return { ...state } })
class Path extends Component {
render() {
diff --git a/src-react/styles/d2h.scss b/src-react/styles/d2h.scss
new file mode 100644
index 0000000..199347a
--- /dev/null
+++ b/src-react/styles/d2h.scss
@@ -0,0 +1,206 @@
+/*
+*
+* Diff to HTML (diff2html.css)
+* Author: rtfpessoa
+* Modified by: codingtwinky
+* Date: Friday 29 August 2014
+* Last Update: Saturday 27 September 2014
+*
+*/
+
+.d2h-wrapper {
+ display: block;
+ margin: 0 auto;
+ text-align: left;
+ width: 100%;
+}
+
+.d2h-file-wrapper {
+ border-radius: 3px;
+}
+
+.d2h-file-header {
+ display: none;
+}
+
+.d2h-file-stats {
+ display: inline;
+ font-size: 12px;
+ text-align: center;
+ max-width: 15%;
+}
+
+.d2h-lines-added {
+ background-color: #ceffce;
+ border: 1px solid #b4e2b4;
+ color: #FFFFFF;
+ border-radius: 5px 0 0 5px;
+ padding: 2px;
+ width: 25px;
+}
+
+.d2h-lines-deleted {
+ background-color: #f7c8c8;
+ border: 1px solid #e9aeae;
+ color: #000000;
+ border-radius: 0 5px 5px 0;
+ padding: 2px;
+ width: 25px;
+}
+
+.d2h-file-name {
+ display: inline;
+ height: 33px;
+ max-width: 80%;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+
+.d2h-diff-table {
+ border-collapse: collapse;
+ font-family: 'Source Code Pro';
+ font-size: 12px;
+ height: 19px;
+ width: 100%;
+ tbody > tr > td {
+ padding: 0px;
+ border-spacing: 0px;
+ height: 105%;
+ }
+}
+
+.d2h-files-diff {
+ width: 100%;
+ display: flex;
+}
+
+.d2h-file-diff {
+ overflow-x: auto;
+ overflow-y: hidden;
+}
+
+.d2h-file-side-diff {
+ display: inline-block;
+ overflow-x: auto;
+ width: 50%;
+}
+
+.d2h-code-line {
+ white-space: pre;
+ padding-left: 10px;
+ padding-right: 10px;
+ display: inline-flex;
+}
+
+.d2h-code-side-line {
+ white-space: pre;
+ padding-left: 5px;
+ padding-right: 5px;
+ display: inline-flex;
+}
+
+.d2h-code-line del,
+.d2h-code-side-line del {
+ display: inline-block;
+ margin-top: -1px;
+ text-decoration: none;
+ background-color: rgba(255, 255, 255, 0.2);
+}
+
+.d2h-code-line ins,
+.d2h-code-side-line ins {
+ display: inline-block;
+ margin-top: -1px;
+ text-decoration: none;
+ background-color: rgba(255, 255, 255, 0.6);
+}
+
+.d2h-code-line-prefix {
+ display: inline-flex;
+ margin-right: 10px;
+}
+
+.line-num1 {
+ display: inline-block;
+ float: left;
+ width: 30px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.line-num2 {
+ display: inline-block;
+ float: right;
+ width: 30px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.d2h-code-linenumber {
+ position: static;
+ width: 52px;
+ min-width: 65px;
+ text-align: center;
+ background-color: #727a83;
+ color: rgba(0, 0, 0, 0.5);
+ border-width: 0 1px 0 1px;
+ cursor: pointer;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ border-left: 1px solid rgba(0, 0, 0, 0.34);
+ border-right: 1px solid rgba(0, 0, 0, 0.34);
+}
+
+.d2h-cntx {
+ color: rgba(255, 255, 255, 0.3);
+}
+
+.d2h-code-side-linenumber {
+ position: static;
+ display: table-cell;
+ width: 52px;
+ min-width: 65px;
+ text-align: center;
+ height: 100%;
+ background-color: rgba(114, 122, 131, 1);
+ color: rgba(0, 0, 0, 0.5);
+ border-width: 0 1px 0 1px;
+ cursor: pointer;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ border-left: 1px solid rgba(0, 0, 0, 0.34);
+ border-right: 1px solid rgba(0, 0, 0, 0.34);
+}
+
+.d2h-del {
+ background-color: #E86756;
+ color: #FFFFFF;
+
+ &.d2h-code-side-linenumber {
+ color: rgba(0, 0, 0, 0.5);
+ }
+}
+
+.d2h-ins {
+ background-color: #66F27B;
+ color: #000000;
+
+ &.d2h-code-side-linenumber {
+ color: rgba(0, 0, 0, 0.5);
+ }
+}
+
+.d2h-info {
+ color: rgba(255, 255, 255, 0.3);
+}
+
+.d2h-code-line-ctn {
+ .word-wrap & {
+ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
+ white-space: -webkit-pre-wrap; /*Chrome & Safari */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* css-3 */
+ }
+}
diff --git a/src-react/styles/fonts/OpenSans.woff b/src-react/styles/fonts/OpenSans.woff
new file mode 100644
index 0000000..55b25f8
Binary files /dev/null and b/src-react/styles/fonts/OpenSans.woff differ
diff --git a/src-react/styles/fonts/SourceCodePro-Medium.woff b/src-react/styles/fonts/SourceCodePro-Medium.woff
new file mode 100644
index 0000000..653d5dd
Binary files /dev/null and b/src-react/styles/fonts/SourceCodePro-Medium.woff differ
diff --git a/src-react/styles/generic.scss b/src-react/styles/generic.scss
new file mode 100644
index 0000000..0c30894
--- /dev/null
+++ b/src-react/styles/generic.scss
@@ -0,0 +1,194 @@
+
+// Generic.less
+// This file can be used to style any page to look like "ungit", i.e. anything that's not
+// application specific goes here.
+
+@import "variables.scss";
+@import "~bootstrap-sass/assets/stylesheets/_bootstrap-mincer.scss";
+@import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss";
+@import "~octicons/octicons/octicons.css";
+
+@font-face {
+ font-family: 'Open Sans';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Open Sans'), local('OpenSans'), url('./fonts/OpenSans.woff') format('woff');
+}
+
+@font-face {
+ font-family: 'Source Code Pro';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Source Code Pro Medium'), local('SourceCodePro-Medium'), url('./fonts/SourceCodePro-Medium.woff') format('woff');
+}
+
+// -- Bootstrap styling ---
+
+.btn {
+ .glyphicon {
+ font-size: 0.8em;
+ margin-right: 0.1em;
+ }
+ &:focus {
+ outline: none;
+ }
+}
+
+.btn, .list-group-item {
+ position: relative;
+ & > .progress {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background: transparent;
+ pointer-events:none;
+ .progress-bar {
+ pointer-events:none;
+ }
+ }
+}
+.btn-group {
+ .btn > .progress {
+ border-radius: 0px;
+ .progress-bar {
+ border-radius: 0px;
+ }
+ }
+}
+
+.panel {
+ border: 0px;
+}
+
+.form-control {
+ border: 0px;
+ color: rgba(255, 255, 255, 0.8);
+}
+
+.list-group-item {
+ background: rgba(0, 0, 0, 0.09);
+ border: 0px;
+ margin-bottom: 3px;
+}
+div.list-group-item {
+ &:hover {
+ background: $list-group-hover-bg;
+ }
+ a:hover {
+ text-decoration: none;
+ }
+}
+
+// -- New generic classes ----
+
+.container.container-wide {
+ width: 100%;
+ padding-left: 40px;
+ padding-right: 40px;
+}
+
+hr {
+ border: 0px;
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
+ background: transparent;
+ height: 0px;
+}
+
+a.disabled {
+ pointer-events: none;
+ opacity: 0.5;
+}
+
+.list-group-item .list-item-remove {
+ position: absolute;
+ right: 0px;
+ top: 0px;
+ background: transparent;
+ border: 0px;
+ opacity: 0.3;
+ &:hover {
+ opacity: 1;
+ }
+}
+
+.arrowContainer {
+ position: relative;
+ &.arrowRight .arrow,
+ &.arrowRight .shadow,
+ &.arrowLeft .arrow,
+ &.arrowLeft .shadow {
+ width: 15px;
+ height: 30px;
+ margin-top: 22px;
+ }
+ &.arrowUp .arrow,
+ &.arrowUp .shadow,
+ &.arrowDown .arrow,
+ &.arrowDown .shadow {
+ width: 30px;
+ height: 15px;
+ }
+ .shadow {
+ position: absolute;
+ left: 5px;
+ top: 5px;
+ }
+ .arrow {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ }
+}
+
+.droparea {
+ position: relative;
+ border-radius: 3px;
+ padding: 0.3em;
+ display: inline-block;
+ background: #2B4C5C;
+ padding: 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ .dropmask {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ }
+ .progress {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ left: 0px;
+ top: 0px;
+ background: transparent;
+ }
+}
+
+
+.text-dimmed {
+ opacity: 0.6;
+}
+
+::-webkit-scrollbar {
+ width: 15px;
+}
+::-webkit-scrollbar-track {
+ background-color: #2B3844;
+}
+::-webkit-scrollbar-thumb {
+ background-color: rgba(255, 255, 255, 0.2);
+}
+::-webkit-scrollbar-button {
+ background-color: rgba(0, 0, 0, 0.2);
+}
+::-webkit-scrollbar-corner {
+ background-color: black;
+}
+
+.create-dir {
+ margin-top: 50px;
+}
diff --git a/src-react/styles/images/branchIcon.svg b/src-react/styles/images/branchIcon.svg
new file mode 100644
index 0000000..8a3c760
--- /dev/null
+++ b/src-react/styles/images/branchIcon.svg
@@ -0,0 +1,103 @@
+
+
+
+
diff --git a/src-react/styles/images/remoteIcon.svg b/src-react/styles/images/remoteIcon.svg
new file mode 100644
index 0000000..269c91d
--- /dev/null
+++ b/src-react/styles/images/remoteIcon.svg
@@ -0,0 +1,65 @@
+
+
+
+
diff --git a/src-react/styles/images/tagIcon.svg b/src-react/styles/images/tagIcon.svg
new file mode 100644
index 0000000..36b6d00
--- /dev/null
+++ b/src-react/styles/images/tagIcon.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/src-react/styles/styles.scss b/src-react/styles/styles.scss
new file mode 100644
index 0000000..42abdf9
--- /dev/null
+++ b/src-react/styles/styles.scss
@@ -0,0 +1,119 @@
+// Styles.less
+// This file contains styling that's only used in this app
+
+@import "generic.scss";
+
+
+// -- Application specific layout ----
+// Needed to properly layout this specific page regardless of the specific bootstrap configuration/styling
+
+.glyphicon-circled {
+ margin-right: 18px;
+ border: 5px solid #686868;
+ border-radius: 100%;
+ padding-bottom: 7px;
+ padding-top: 6px;
+ padding-right: 20px;
+ padding-left: 7px;
+}
+
+.repository-actions {
+ position: absolute;
+ margin-top: 20px;
+ right: 0px;
+ z-index: 30;
+}
+
+.crash {
+ margin-top: 20px;
+}
+
+// -- Application specific styling ----
+.btn-load-more {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ .btn {
+ margin-right: auto;
+ margin-left: auto;
+ display: table;
+ }
+}
+
+.ui-autocomplete {
+ background: rgba(200, 210, 230, 1);
+ box-shadow: 13px 13px 0px rgba(0, 0, 0, 0.2);
+ border-radius: 5px;
+ margin-top: 3px;
+ position: absolute;
+ display: block;
+ left: 0px;
+ top: 0px;
+ z-index: 100;
+ list-style: none;
+ padding-left: 0px;
+ margin-left: 0px;
+ padding: 3px;
+ .ui-menu-item {
+ list-style-type: none;
+ a {
+ padding: 2px;
+ padding-left: 4px;
+ border-radius: 3px;
+ display: block;
+ color: rgba(0, 0, 0, 0.6);
+ cursor: pointer;
+ text-decoration: none;
+ &.ui-state-focus, &.ui-state-active {
+ background: rgba(11, 26, 51, 1);
+ color: #fff;
+ }
+ }
+ }
+}
+
+.app-top-margin {
+ margin-top: 15px
+}
+
+.list-link {
+ float: right;
+ display: inline;
+ margin-top: -23px;
+}
+
+.dropdown-menu {
+ li {
+ a {
+ &.list-url {
+ padding: 0px 4px 0px 4px;
+ margin-right: 30px;
+ }
+
+ &.list-remove {
+ padding: 0px 4px 0px 4px;
+ margin-right: 10px;
+ }
+ }
+ }
+}
+
+.remote-icon {
+ background: url('./images/remoteIcon.svg');
+ width: 12px;
+ height: 10px;
+ display: inline-block;
+}
+
+.branch-icon {
+ background: url('./images/branchIcon.svg');
+ width: 9px;
+ height: 10px;
+ display: inline-block;
+}
+
+.tag-icon {
+ background: url('./images/tagIcon.svg');
+ width: 5px;
+ height: 10px;
+ display: inline-block;
+}
diff --git a/src-react/styles/variables.scss b/src-react/styles/variables.scss
new file mode 100644
index 0000000..43a2d40
--- /dev/null
+++ b/src-react/styles/variables.scss
@@ -0,0 +1,32 @@
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/_variables.scss";
+
+// -- Application specific variables ----
+$log-width-small: 400px;
+$log-width-large: 550px;
+
+// -- Bootstrap variables ---
+$navbar-default-bg: #2B3844;
+$font-family-sans-serif: 'Open Sans';
+$font-family-monospace: 'Source Code Pro';
+$body-bg: #252833;
+$progress-bg: rgba(0, 0, 0, 0.2);
+$progress-bar-bg: rgba(0, 0, 0, 0.2);
+$text-color: #D8D8D8;
+$text-muted: #707A85;
+$panel-bg: #3C4653;
+$panel-default-text: $text-color;
+$panel-default-heading-bg: #2C3541;
+$panel-default-border: #362C36;
+$list-group-bg: transparent;
+$list-group-hover-bg: rgba(0, 0, 0, 0.2);
+$list-group-border: #435158;
+$list-group-link-heading-color: rgba(255, 255, 255, 0.8);
+$list-group-link-color: rgba(255, 255, 255, 0.5);
+$modal-content-bg: $panel-bg;
+$modal-header-border-color: $list-group-border;
+$input-bg: rgba(255, 255, 255, 0.1);
+$input-color-placeholder: rgba(255, 255, 255, 0.3);
+$btn-default-bg: #556666;
+$btn-default-color: $text-color;
+$btn-default-border: rgba(0, 0, 0, 0.1);
+$link-hover-color: lighten($link-color, 15%);