Allows tabs to work with multiple browsers and scrollbars
This commit is contained in:
parent
edd7f5eb27
commit
4070d7deee
8 changed files with 68 additions and 21 deletions
|
@ -42,7 +42,8 @@ export default RepoFile;
|
||||||
<template>
|
<template>
|
||||||
<tr v-if="!loading.tree || hasFiles" :class="{'active': activeFile.url === file.url}">
|
<tr v-if="!loading.tree || hasFiles" :class="{'active': activeFile.url === file.url}">
|
||||||
<td>
|
<td>
|
||||||
<i class="fa" :class="file.icon" :style="{'margin-left': file.level * 10 + 'px'}"></i>
|
<i class="fa" v-if="!file.loading" :class="file.icon" :style="{'margin-left': file.level * 10 + 'px'}"></i>
|
||||||
|
<i class="fa fa-spinner fa-spin" v-if="file.loading" :style="{'margin-left': file.level * 10 + 'px'}"></i>
|
||||||
<a :href="file.url" @click.prevent="linkClicked(file)" class="repo-file-name" :title="file.url">{{file.name}}</a>
|
<a :href="file.url" @click.prevent="linkClicked(file)" class="repo-file-name" :title="file.url">{{file.name}}</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|
|
@ -94,14 +94,14 @@ const RepoHelper = {
|
||||||
return oldList;
|
return oldList;
|
||||||
},
|
},
|
||||||
|
|
||||||
getContent(treeOrFile) {
|
getContent(treeOrFile, cb) {
|
||||||
let file = treeOrFile;
|
let file = treeOrFile;
|
||||||
const loadingData = RepoHelper.setLoading(true);
|
// const loadingData = RepoHelper.setLoading(true);
|
||||||
|
|
||||||
Service.getContent()
|
Service.getContent()
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const data = response.data;
|
const data = response.data;
|
||||||
RepoHelper.setLoading(false, loadingData);
|
// RepoHelper.setLoading(false, loadingData);
|
||||||
|
if(cb) cb();
|
||||||
Store.isTree = RepoHelper.isTree(data);
|
Store.isTree = RepoHelper.isTree(data);
|
||||||
if (!Store.isTree) {
|
if (!Store.isTree) {
|
||||||
if (!file) file = data;
|
if (!file) file = data;
|
||||||
|
@ -153,6 +153,7 @@ const RepoHelper = {
|
||||||
const simpleBlob = RepoHelper.serializeRepoEntity('blob', blob);
|
const simpleBlob = RepoHelper.serializeRepoEntity('blob', blob);
|
||||||
simpleBlob.lastCommitMessage = blob.last_commit.message;
|
simpleBlob.lastCommitMessage = blob.last_commit.message;
|
||||||
simpleBlob.lastCommitUpdate = blob.last_commit.committed_date;
|
simpleBlob.lastCommitUpdate = blob.last_commit.committed_date;
|
||||||
|
simpleBlob.loading = false;
|
||||||
|
|
||||||
return simpleBlob;
|
return simpleBlob;
|
||||||
},
|
},
|
||||||
|
@ -174,6 +175,7 @@ const RepoHelper = {
|
||||||
url,
|
url,
|
||||||
icon: RepoHelper.toFA(icon),
|
icon: RepoHelper.toFA(icon),
|
||||||
level: 0,
|
level: 0,
|
||||||
|
loading: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -43,19 +43,27 @@ export default class RepoSidebar {
|
||||||
linkClicked(clickedFile) {
|
linkClicked(clickedFile) {
|
||||||
let url = '';
|
let url = '';
|
||||||
let file = clickedFile;
|
let file = clickedFile;
|
||||||
|
file.loading = true;
|
||||||
if (typeof file === 'object') {
|
if (typeof file === 'object') {
|
||||||
if (file.type === 'tree' && file.opened) {
|
if (file.type === 'tree' && file.opened) {
|
||||||
file = Store.removeChildFilesOfTree(file);
|
file = Store.removeChildFilesOfTree(file);
|
||||||
} else {
|
} else {
|
||||||
url = file.url;
|
url = file.url;
|
||||||
Service.url = url;
|
Service.url = url;
|
||||||
Helper.getContent(file);
|
// I need to refactor this to do the `then` here.
|
||||||
|
// Not a callback. For now this is good enough.
|
||||||
|
// it works.
|
||||||
|
Helper.getContent(file, () => {
|
||||||
|
file.loading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (typeof file === 'string') {
|
} else if (typeof file === 'string') {
|
||||||
// go back
|
// go back
|
||||||
url = file;
|
url = file;
|
||||||
Service.url = url;
|
Service.url = url;
|
||||||
Helper.getContent();
|
Helper.getContent(null, () => {
|
||||||
|
file.loading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,6 +16,10 @@ const RepoStore = {
|
||||||
blobRaw: '',
|
blobRaw: '',
|
||||||
blobRendered: '',
|
blobRendered: '',
|
||||||
openedFiles: [],
|
openedFiles: [],
|
||||||
|
tabSize: 100,
|
||||||
|
defaultTabSize: 100,
|
||||||
|
minTabSize: 30,
|
||||||
|
tabsOverflow: 41,
|
||||||
activeFile: {
|
activeFile: {
|
||||||
active: true,
|
active: true,
|
||||||
binary: false,
|
binary: false,
|
||||||
|
@ -29,6 +33,7 @@ const RepoStore = {
|
||||||
raw: false,
|
raw: false,
|
||||||
newContent: '',
|
newContent: '',
|
||||||
changed: false,
|
changed: false,
|
||||||
|
loading: false
|
||||||
},
|
},
|
||||||
activeFileIndex: 0,
|
activeFileIndex: 0,
|
||||||
activeLine: 0,
|
activeLine: 0,
|
||||||
|
@ -136,6 +141,7 @@ const RepoStore = {
|
||||||
mime_type: 'loading',
|
mime_type: 'loading',
|
||||||
name: 'loading',
|
name: 'loading',
|
||||||
url: randomURL,
|
url: randomURL,
|
||||||
|
fake: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
RepoStore.openedFiles.push(newFakeFile);
|
RepoStore.openedFiles.push(newFakeFile);
|
||||||
|
|
|
@ -38,7 +38,7 @@ export default RepoTab;
|
||||||
<i class="fa" :class="changedClass"></i>
|
<i class="fa" :class="changedClass"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="#" v-if="!tab.loading" :title="tab.url" @click.prevent="tabClicked(tab)">{{tab.name}}</a>
|
<a href="#" class="repo-tab" v-if="!tab.loading" :title="tab.url" @click.prevent="tabClicked(tab)">{{tab.name}}</a>
|
||||||
|
|
||||||
<i v-if="tab.loading" class="fa fa-spinner fa-spin"></i>
|
<i v-if="tab.loading" class="fa fa-spinner fa-spin"></i>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -17,6 +17,23 @@ export default class RepoTabs {
|
||||||
'repo-tab': RepoTab,
|
'repo-tab': RepoTab,
|
||||||
},
|
},
|
||||||
data: () => Store,
|
data: () => Store,
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
isOverflow() {
|
||||||
|
let tabs = document.getElementById('tabs');
|
||||||
|
if(tabs) {
|
||||||
|
return tabs.scrollWidth > tabs.offsetWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
openedFiles() {
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
this.tabsOverflow = this.isOverflow();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#tabs {
|
#tabs {
|
||||||
height: 51px;
|
height: 61px;
|
||||||
border-bottom: 1px solid $white-normal;
|
border-bottom: 1px solid $white-normal;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
@ -65,12 +65,22 @@
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|
||||||
|
&.overflown {
|
||||||
|
height: 61px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 20px 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
animation: fadein 0.5s;
|
animation: swipeRightAppear ease-in 0.1s;
|
||||||
|
animation-iteration-count: 1;
|
||||||
|
transform-origin: 0% 50%;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
background: $gray-normal;
|
background: $gray-normal;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 10px 18px;
|
padding: 20px 18px;
|
||||||
border-right: 1px solid $border-color;
|
border-right: 1px solid $border-color;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
@ -85,6 +95,7 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
&.close {
|
&.close {
|
||||||
width: auto;
|
width: auto;
|
||||||
|
@ -110,10 +121,10 @@
|
||||||
background: $gray-light;
|
background: $gray-light;
|
||||||
border-bottom: 1px solid $white-normal;
|
border-bottom: 1px solid $white-normal;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
margin-top: -15px;
|
|
||||||
padding: 10px 5px;
|
padding: 10px 5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-top: 1px solid $white-normal;
|
border-top: 1px solid $white-normal;
|
||||||
|
margin-top: -5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#binary-viewer {
|
#binary-viewer {
|
||||||
|
@ -319,12 +330,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadein {
|
@keyframes swipeRightAppear {
|
||||||
from {
|
0% {
|
||||||
opacity: 0;
|
transform: scaleX(0.00) ;
|
||||||
}
|
}
|
||||||
|
45% {
|
||||||
to {
|
transform: scaleX(0.26) ;
|
||||||
opacity: 1;
|
}
|
||||||
|
100% {
|
||||||
|
transform: scaleX(1.00) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,14 @@
|
||||||
%tr{ is: "repo-file-options", ":is-mini" => "isMini", "project-name" => @project.name }
|
%tr{ is: "repo-file-options", ":is-mini" => "isMini", "project-name" => @project.name }
|
||||||
%tr{ is: "repo-previous-directory", ":prev-url" => "prevURL", "@linkclicked" => "linkClicked(prevURL)" }
|
%tr{ is: "repo-previous-directory", ":prev-url" => "prevURL", "@linkclicked" => "linkClicked(prevURL)" }
|
||||||
%tr{ is: "repo-loading-file", "v-for" => "n in 5", ":loading" => "loading", ":has-files" => "!!files.length", ":is-mini" => "isMini" }
|
%tr{ is: "repo-loading-file", "v-for" => "n in 5", ":loading" => "loading", ":has-files" => "!!files.length", ":is-mini" => "isMini" }
|
||||||
%tr{ is: "repo-file", "v-for" => "file in files", ":key" => "file.id", ":file" => "file",":is-mini" => "isMini", "@linkclicked" => "linkClicked(file)", ":is-tree" => "isTree", ":loading" => "loading", ":has-files" => "!!files.length", ":active-file" => "activeFile" }
|
%tr{ is: "repo-file", "v-for" => "file in files", ":key" => "file.id", ":file" => "file",":is-mini" => "isMini", "@linkclicked" => "linkClicked(file)", ":is-tree" => "isTree", ":has-files" => "!!files.length", ":active-file" => "activeFile" }
|
||||||
.panel-right>
|
.panel-right>
|
||||||
%ul#tabs{ "v-if" => "isMini", "v-cloak" => "1" }
|
%ul#tabs{ "v-if" => "isMini", "v-cloak" => "1", ":class" => "{'overflown': tabsOverflow}" }
|
||||||
%li{ is: "repo-tab", "v-for" => "tab in openedFiles", ":key" => "tab.id", ":tab" => "tab", ":class" => "{'active' : tab.active}" }
|
%li{ is: "repo-tab", "v-for" => "tab in openedFiles", ":key" => "tab.id", ":tab" => "tab", ":class" => "{'active' : tab.active}" }
|
||||||
#repo-file-buttons
|
#repo-file-buttons
|
||||||
#ide{ data: { url: repo_url(@project) } }
|
#ide{ data: { url: repo_url(@project) } }
|
||||||
#binary-viewer{ "v-if" => "binary" }
|
#binary-viewer{ "v-if" => "binary" }
|
||||||
%img{ "v-if" => "binaryTypes.png", ":src" => "pngBlobWithDataURI", ":alt" => "activeFile.name", alt: '' }
|
%img{ "v-if" => "binaryTypes.png", ":src" => "pngBlobWithDataURI", ":alt" => "activeFile.name", alt: "" }
|
||||||
%div{ "v-if" => "binaryTypes.markdown", "v-html" => "activeFile.html" }
|
%div{ "v-if" => "binaryTypes.markdown", "v-html" => "activeFile.html" }
|
||||||
#commit-area{ "v-if" => "changedFiles.length" }
|
#commit-area{ "v-if" => "changedFiles.length" }
|
||||||
%form.form-horizontal
|
%form.form-horizontal
|
||||||
|
|
Loading…
Reference in a new issue