Skip to content

Commit

Permalink
WIP: copy apps/settings/.../LanguageSection to apps-custom/simplesett…
Browse files Browse the repository at this point in the history
…ings
  • Loading branch information
tanyaka committed Jul 12, 2024
1 parent 9f367f0 commit eac41d2
Show file tree
Hide file tree
Showing 8 changed files with 715 additions and 0 deletions.
62 changes: 62 additions & 0 deletions lib/Controller/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,24 @@
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\Authentication\Exceptions\InvalidTokenException;
use OCP\IConfig;
use OCP\ISession;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\Session\Exceptions\SessionNotAvailableException;

/**
* @psalm-suppress UnusedClass
*/
class PageController extends Controller {
/** @var IConfig */
private $config;

/** @var IFactory */
private $l10nFactory;

/** @var IInitialState */
private $initialState;

Expand All @@ -55,12 +65,18 @@ class PageController extends Controller {
private $uid;

public function __construct(
IConfig $config,
IUserManager $userManager,
IFactory $l10nFactory,
IAuthTokenProvider $tokenProvider,
ISession $session,
IInitialState $initialState,
IUserSession $userSession,
?string $UserId
) {
$this->config = $config;
$this->userManager = $userManager;
$this->l10nFactory = $l10nFactory;
$this->tokenProvider = $tokenProvider;
$this->session = $session;
$this->initialState = $initialState;
Expand All @@ -83,6 +99,15 @@ public function index(): TemplateResponse {
$this->userSession->getImpersonatingUserID() === null
);

$user = $this->userManager->get($this->uid);

$this->initialState->provideInitialState(
'personalInfoParameters',
[
'languageMap' => $this->getLanguageMap($user),
]
);

return new TemplateResponse(
Application::APP_ID,
'index',
Expand Down Expand Up @@ -115,4 +140,41 @@ private function getAppTokens(): array {
return $data;
}, $tokens);
}

/**
* returns the user's active language, common languages, and other languages in an
* associative array
*/
private function getLanguageMap(IUser $user): array {
$forceLanguage = $this->config->getSystemValue('force_language', false);
if ($forceLanguage !== false) {
return [];
}

$uid = $user->getUID();

$userConfLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
$languages = $this->l10nFactory->getLanguages();

// associate the user language with the proper array
$userLangIndex = array_search($userConfLang, array_column($languages['commonLanguages'], 'code'));
$userLang = $languages['commonLanguages'][$userLangIndex];
// search in the other languages
if ($userLangIndex === false) {
$userLangIndex = array_search($userConfLang, array_column($languages['otherLanguages'], 'code'));
$userLang = $languages['otherLanguages'][$userLangIndex];
}
// if user language is not available but set somehow: show the actual code as name
if (!is_array($userLang)) {
$userLang = [
'code' => $userConfLang,
'name' => $userConfLang,
];
}

return array_merge(
['activeLanguage' => $userLang],
$languages
);
}
}
4 changes: 4 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.

<template>
<content>
<LanguageSection />
<hr>
<AuthTokenSection />
<hr>
<WebDavUrl />
Expand All @@ -30,11 +32,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import AuthTokenSection from './components/security/AuthTokenSection.vue'
import WebDavUrl from './components/files/WebDavUrl.vue'
import Software from './components/help/Software.vue'
import LanguageSection from './components/LanguageSection/LanguageSection.vue'
import { defineComponent } from 'vue'

export default defineComponent({
name: 'App',
components: {
LanguageSection,
AuthTokenSection,
WebDavUrl,
Software,
Expand Down
138 changes: 138 additions & 0 deletions src/components/LanguageSection/Language.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<!--
- @copyright 2021, Christopher Ng <chrng8@gmail.com>
-
- @author Christopher Ng <[email protected]>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->

<template>
<div class="language">
<NcSelect :aria-label-listbox="t('simplesettings', 'Languages')"
class="language__select"
:clearable="false"
:input-id="inputId"
label="name"
label-outside
:options="allLanguages"
:value="language"
@option:selected="onLanguageChange" />
</div>
</template>

<script>
import { ACCOUNT_SETTING_PROPERTY_ENUM } from '../../constants/AccountPropertyConstants.js'
import { savePrimaryAccountProperty } from '../../service/PersonalInfo/PersonalInfoService.js'
import { validateLanguage } from '../../utils/validate.js'
import { handleError } from '../../utils/handlers.js'

import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'

export default {
name: 'Language',

components: {
NcSelect,
},

props: {
inputId: {
type: String,
default: null,
},
commonLanguages: {
type: Array,
required: true,
},
otherLanguages: {
type: Array,
required: true,
},
language: {
type: Object,
required: true,
},
},

data() {
return {
initialLanguage: this.language,
}
},

computed: {
/**
* All available languages, sorted like: current, common, other
*/
allLanguages() {
const common = this.commonLanguages.filter(l => l.code !== this.language.code)
const other = this.otherLanguages.filter(l => l.code !== this.language.code)
return [this.language, ...common, ...other]
},
},

methods: {
async onLanguageChange(language) {
this.$emit('update:language', language)

if (validateLanguage(language)) {
await this.updateLanguage(language)
}
},

async updateLanguage(language) {
try {
const responseData = await savePrimaryAccountProperty(ACCOUNT_SETTING_PROPERTY_ENUM.LANGUAGE, language.code)
this.handleResponse({
language,
status: responseData.ocs?.meta?.status,
})
window.location.reload()
} catch (e) {
this.handleResponse({
errorMessage: t('settings', 'Unable to update language'),
error: e,
})
}
},

handleResponse({ language, status, errorMessage, error }) {
if (status === 'ok') {
// Ensure that local state reflects server state
this.initialLanguage = language
} else {
handleError(error, errorMessage)
}
},
},
}
</script>

<style lang="scss" scoped>
.language {
display: grid;

#{&}__select {
margin-top: 6px; // align with other inputs
}

a {
text-decoration: none;
width: max-content;
}
}
</style>
77 changes: 77 additions & 0 deletions src/components/LanguageSection/LanguageSection.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!--
- @copyright 2021, Christopher Ng <chrng8@gmail.com>
-
- @author Christopher Ng <[email protected]>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->

<template>
<section class="section">
<h2>{{ t('simplesettings', 'Language') }}</h2>
<Language v-if="isEditable"
:input-id="inputId"
:common-languages="commonLanguages"
:other-languages="otherLanguages"
:language.sync="language" />

<span v-else>
{{ t('settings', 'No language set') }}
</span>
</section>
</template>

<script>
import { loadState } from '@nextcloud/initial-state'
import Language from './Language.vue'
import { ACCOUNT_SETTING_PROPERTY_ENUM, ACCOUNT_SETTING_PROPERTY_READABLE_ENUM } from '../../constants/AccountPropertyConstants.js'

const { languageMap: { activeLanguage, commonLanguages, otherLanguages } } = loadState('simplesettings', 'personalInfoParameters', {})

export default {
name: 'LanguageSection',

components: {
Language,
},

setup() {
// Non reactive instance properties
return {
commonLanguages,
otherLanguages,
propertyReadable: ACCOUNT_SETTING_PROPERTY_READABLE_ENUM.LANGUAGE,
}
},

data() {
return {
language: activeLanguage,
}
},

computed: {
inputId() {
return `account-setting-${ACCOUNT_SETTING_PROPERTY_ENUM.LANGUAGE}`
},

isEditable() {
return Boolean(this.language)
},
},
}
</script>
Loading

0 comments on commit eac41d2

Please sign in to comment.