feat: add rtl support (#2178)

pull/2184/head
thewh1teagle 2022-10-21 19:07:11 +03:00 committed by GitHub
parent a49105db1d
commit 2c14146a31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 152 additions and 1 deletions

View File

@ -16,6 +16,10 @@
transition: .2s ease transform; transition: .2s ease transform;
} }
body.rtl .shell {
direction: ltr;
}
.shell__result { .shell__result {
display: flex; display: flex;
padding: 0.5em; padding: 0.5em;

View File

@ -5,6 +5,10 @@ body {
color: #333333; color: #333333;
} }
body.rtl {
direction: rtl;
}
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
@ -58,6 +62,11 @@ nav {
left: 0; left: 0;
} }
body.rtl nav {
left: unset;
right: 0;
}
nav .action { nav .action {
width: 100%; width: 100%;
display: block; display: block;
@ -69,6 +78,11 @@ nav .action {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
body.rtl .action {
direction: rtl;
text-align: right;
}
nav > div { nav > div {
border-top: 1px solid rgba(0, 0, 0, 0.05); border-top: 1px solid rgba(0, 0, 0, 0.05);
} }
@ -101,6 +115,10 @@ main {
border-radius: 0.125em; border-radius: 0.125em;
} }
body.rtl .breadcrumbs a {
transform: translateX(-16em);
}
.breadcrumbs a:hover { .breadcrumbs a:hover {
background-color: rgba(0, 0, 0, 0.05); background-color: rgba(0, 0, 0, 0.05);
} }

View File

@ -8,6 +8,10 @@
flex-wrap: wrap; flex-wrap: wrap;
} }
body.rtl .dashboard .row {
margin-right: 16em;
}
.dashboard .row .column { .dashboard .row .column {
display: flex; display: flex;
padding: 0 .5em; padding: 0 .5em;
@ -60,6 +64,10 @@ p code {
border-bottom: 2px solid rgba(0, 0, 0, 0.05); border-bottom: 2px solid rgba(0, 0, 0, 0.05);
} }
body.rtl #nav .wrapper {
margin-right: 16em;
}
.dashboard #nav ul { .dashboard #nav ul {
list-style: none; list-style: none;
display: flex; display: flex;
@ -138,6 +146,13 @@ table tr>*:first-child {
padding-left: 1em; padding-left: 1em;
} }
body.rtl table tr>* {
padding-left: unset;
padding-right: 1em;
text-align: right;
direction: ltr;
}
table tr>*:last-child { table tr>*:last-child {
padding-right: 1em; padding-right: 1em;
} }
@ -181,6 +196,11 @@ table tr>*:last-child {
margin-right: auto; margin-right: auto;
} }
body.rtl .card .card-title>*:first-child {
margin-right: 0;
text-align: right;
}
.card>div { .card>div {
padding: 1em 1em; padding: 1em 1em;
} }
@ -462,3 +482,9 @@ table tr>*:last-child {
font-size: 1.5em; font-size: 1.5em;
font-weight: 500; font-weight: 500;
} }
/*** RTL - Fix disk usage information (in english) ***/
body.rtl .credits {
text-align: right;
direction: ltr;
}

View File

@ -135,10 +135,25 @@ header .menu-button {
z-index: 1; z-index: 1;
} }
body.rtl #search #result {
direction: ltr;
}
#search #result>div>*:first-child { #search #result>div>*:first-child {
margin-top: 0; margin-top: 0;
} }
body.rtl #search #result {
direction: rtl;
text-align: right;
}
/*** RTL - Keep search result LTR because it has paths (in english) ***/
body.rtl #search #result ul>* {
direction: ltr;
text-align: left;
}
#search.active #result { #search.active #result {
padding: .5em; padding: .5em;
height: calc(100% - 4em); height: calc(100% - 4em);
@ -224,6 +239,10 @@ header .menu-button {
padding: .5em; padding: .5em;
} }
body.rtl #search .boxes h3 {
text-align: right;
}
#search .boxes>div { #search .boxes>div {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;

View File

@ -2,6 +2,10 @@
--item-selected: white; --item-selected: white;
} }
body.rtl #listing {
margin-right: 16em;
}
#listing h2 { #listing h2 {
margin: 0 0 0 0.5em; margin: 0 0 0 0.5em;
font-size: .9em; font-size: .9em;

View File

@ -40,6 +40,13 @@
transform-origin: top right; transform-origin: top right;
z-index: 99999; z-index: 99999;
} }
body.rtl #dropdown {
right: unset;
left: 1em;
transform-origin: top left;
}
#dropdown > div { #dropdown > div {
display: block; display: block;
} }
@ -95,9 +102,20 @@
transition: .1s ease left; transition: .1s ease left;
left: -17em; left: -17em;
} }
body.rtl nav {
left: unset;
right: -17em;
}
nav.active { nav.active {
left: 0; left: 0;
} }
body.rtl nav.active {
left: unset;
right: 0;
}
header .search-button, header .search-button,
header .menu-button { header .menu-button {
display: inherit; display: inherit;
@ -108,6 +126,23 @@
#listing { #listing {
margin-bottom: 5em; margin-bottom: 5em;
} }
body.rtl #listing {
margin-right: unset;
}
body.rtl .breadcrumbs {
transform: translateX(16em);
}
body.rtl #nav .wrapper {
margin-right: unset;
}
body.rtl .dashboard .row {
margin-right: unset;
}
main { main {
margin: 0 1em; margin: 0 1em;
width: calc(100% - 2em); width: calc(100% - 2em);

View File

@ -315,6 +315,11 @@ main .spinner .bounce2 {
padding: 0 1em; padding: 0 1em;
} }
/*** RTL - flip and position arrow of path ***/
body.rtl .breadcrumbs .chevron {
transform: scaleX(-1) translateX(16em);
}
#editor-container .breadcrumbs span { #editor-container .breadcrumbs span {
font-size: .75rem; font-size: .75rem;
} }
@ -404,3 +409,22 @@ main .spinner .bounce2 {
} }
@import './mobile.css'; @import './mobile.css';
/* * * * * * * * * * * * * * * *
* RTL overrides *
* * * * * * * * * * * * * * * */
body.rtl .card-content textarea {
direction: ltr;
text-align: left;
}
body.rtl .card-content .small + input {
direction: ltr;
text-align: left;
}
body.rtl .card.floating .card-content .file-list {
direction: ltr;
text-align: left;
}

View File

@ -100,6 +100,8 @@ const removeEmpty = (obj) =>
{} {}
); );
export const rtlLanguages = ["he", "ar"];
const i18n = new VueI18n({ const i18n = new VueI18n({
locale: detectLocale(), locale: detectLocale(),
fallbackLocale: "en", fallbackLocale: "en",

View File

@ -13,7 +13,7 @@ import Shares from "@/views/settings/Shares";
import Errors from "@/views/Errors"; import Errors from "@/views/Errors";
import store from "@/store"; import store from "@/store";
import { baseURL, name } from "@/utils/constants"; import { baseURL, name } from "@/utils/constants";
import i18n from "@/i18n"; import i18n, { rtlLanguages } from "@/i18n";
Vue.use(Router); Vue.use(Router);
@ -158,6 +158,18 @@ router.beforeEach((to, from, next) => {
const title = i18n.t(titles[to.name]); const title = i18n.t(titles[to.name]);
document.title = title + " - " + name; document.title = title + " - " + name;
/*** RTL related settings per route ****/
const rtlSet = document.querySelector("body").classList.contains("rtl");
const shouldSetRtl = rtlLanguages.includes(i18n.locale);
switch (true) {
case shouldSetRtl && !rtlSet:
document.querySelector("body").classList.add("rtl");
break;
case !shouldSetRtl && rtlSet:
document.querySelector("body").classList.remove("rtl");
break;
}
if (to.matched.some((record) => record.meta.requiresAuth)) { if (to.matched.some((record) => record.meta.requiresAuth)) {
if (!store.getters.isLogged) { if (!store.getters.isLogged) {
next({ next({

View File

@ -75,6 +75,7 @@
import { mapState, mapMutations } from "vuex"; import { mapState, mapMutations } from "vuex";
import { users as api } from "@/api"; import { users as api } from "@/api";
import Languages from "@/components/settings/Languages"; import Languages from "@/components/settings/Languages";
import i18n, { rtlLanguages } from "@/i18n";
export default { export default {
name: "settings", name: "settings",
@ -143,6 +144,9 @@ export default {
singleClick: this.singleClick, singleClick: this.singleClick,
dateFormat: this.dateFormat, dateFormat: this.dateFormat,
}; };
const shouldReload =
rtlLanguages.includes(data.locale) !==
rtlLanguages.includes(i18n.locale);
await api.update(data, [ await api.update(data, [
"locale", "locale",
"hideDotfiles", "hideDotfiles",
@ -150,6 +154,9 @@ export default {
"dateFormat", "dateFormat",
]); ]);
this.updateUser(data); this.updateUser(data);
if (shouldReload) {
location.reload();
}
this.$showSuccess(this.$t("settings.settingsUpdated")); this.$showSuccess(this.$t("settings.settingsUpdated"));
} catch (e) { } catch (e) {
this.$showError(e); this.$showError(e);