diff --git a/app/controllers/configuration-controller.php b/app/controllers/configuration-controller.php index 821c52c..285e503 100644 --- a/app/controllers/configuration-controller.php +++ b/app/controllers/configuration-controller.php @@ -5,10 +5,24 @@ namespace Sakura\Controllers; use WP_REST_Server; use WP_REST_Request; use WP_Error; +use Sakura\Lib\Exception; use Sakura\Models\OptionModel; class ConfigurationController extends BaseController { + public function public_options() + { + $keys = [ + // key => default value + 'title' => 'Theme Sakura', + ]; + $res = []; + foreach ($keys as $key => $default) { + $res[$key] = $this->sakura_options($key, $default); + } + return $res; + } + /** * Constructor. * @@ -23,7 +37,7 @@ class ConfigurationController extends BaseController /** * Registers the routes for comments. * - * @since 4.7.0 + * @since 5.0.0 * * @see register_rest_route() */ @@ -39,12 +53,6 @@ class ConfigurationController extends BaseController 'permission_callback' => array($this, 'get_config_permissions_check'), // 'args' => $this->get_collection_params(), ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array($this, 'create_config'), - 'permission_callback' => array($this, 'create_config_permissions_check'), - // 'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE), - ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array($this, 'update_config'), @@ -75,7 +83,7 @@ class ConfigurationController extends BaseController return true; } - public function create_config(WP_REST_Request $request) + public function update_config(WP_REST_Request $request) { $original = (array) $this->get_config($request); $json = (array) self::json_validate($request->get_body()); @@ -83,8 +91,7 @@ class ConfigurationController extends BaseController return $original; } - $config = OptionModel::create($this->rest_base, $json); - $config = $config ? $config : OptionModel::update($this->rest_base, $json); + $config = OptionModel::update($this->rest_base, $json); if (!$config) { return new WP_Error( 'save_config_failure', @@ -96,25 +103,51 @@ class ConfigurationController extends BaseController } } - public function create_config_permissions_check(WP_REST_Request $request) - { - return true; - } - - public function update_config(WP_REST_Request $request) - { - return $this->create_config($request); - } - public function update_config_permissions_check(WP_REST_Request $request) { return true; } + public function inite_theme() + { + $config = OptionModel::create($this->rest_base, (array)[]); + } + public static function json_validate(string $string) { $json = json_decode($string); return $json; } + + public function set_key_value(string $key, $value) + { + $json = (array) OptionModel::get($this->rest_base); + if (!$json) { + return new WP_Error( + 'no_such_option', + __('Maybe you should save the configuration bufore using it.', self::$text_domain), + array('status' => 500) + ); + } + $json[$key] = $value; + $config = OptionModel::update($this->rest_base, $json); + $config = $config ? $config : OptionModel::create($this->rest_base, $json); + return $config; + } + + public function sakura_options(string $namespace, $default) + { + $config = (array) OptionModel::get($this->rest_base); + if (array_key_exists($namespace, $config)) { + return $config[$namespace]; + } else { + $this->set_key_value($namespace, $default); + return $default; + } + // translators: %s: $namespace */ + // throw new Exception( + // sprintf(__("No existing database saving value or default value for option '%s'.", self::$text_domain), $namespace) + // ); + } } diff --git a/app/controllers/init-state-controller.php b/app/controllers/init-state-controller.php index 3a4e4ff..3f7e976 100644 --- a/app/controllers/init-state-controller.php +++ b/app/controllers/init-state-controller.php @@ -5,8 +5,6 @@ namespace Sakura\Controllers; use WP_REST_Response; use WP_REST_Request; use WP_Rewrite; -use Sakura\Controllers\MenuController; -use Sakura\Controllers\CommentController; class InitStateController extends BaseController { @@ -33,6 +31,7 @@ class InitStateController extends BaseController 'menus' => (new MenuController)->get_menus(), // 'rewrite_rules' => (new \WP_Rewrite())->rewrite_rules(), 'index' => (new WP_Rewrite())->index, + 'config' => (new ConfigurationController)->public_options(), 'recaptcha_site_key' => '6LfHEoEbAAAAAI5p_XBlr1WxEvrsOSNQFCQNcT79', // v2 secret key: 6LfHEoEbAAAAAIh0w2I9PCcVoa0j71mO6t7fipsj // 'recaptcha_site_key' => '6LdKhX8bAAAAAF5HJprXtKvg3nfBJMfgd2o007PN' // v3 secret key: 6LdKhX8bAAAAAA010EXlQ32FWoYD1J2sLb8SaYLR ); diff --git a/app/functions.php b/app/functions.php index 0c286ce..3936f29 100644 --- a/app/functions.php +++ b/app/functions.php @@ -11,13 +11,19 @@ define('SAKURA_DEVEPLOMENT_HOST', 'http://127.0.0.1:9000'); // PHP loaders require_once(__DIR__ . '/loader.php'); -new \Sakura\Helpers\SetupHelper(); -new \Sakura\Helpers\WhoopsHelper(); -new \Sakura\Helpers\ViteHelper(); -new \Sakura\Helpers\AdminPageHelper(); -new \Sakura\Helpers\CustomMenuMetaFieldsHelper(); -new \Sakura\Helpers\CommentHelper(); -new \Sakura\Helpers\PostQueryHelper('post'); +new Sakura\Helpers\SetupHelper(); +new Sakura\Helpers\WhoopsHelper(); +new Sakura\Helpers\ViteHelper(); +new Sakura\Helpers\AdminPageHelper(); +new Sakura\Helpers\CustomMenuMetaFieldsHelper(); +new Sakura\Helpers\CommentHelper(); +new Sakura\Helpers\PostQueryHelper('post'); -new \Sakura\Routers\ApiRouter(); -new \Sakura\Routers\PagesRouter(); +new Sakura\Routers\ApiRouter(); +new Sakura\Routers\PagesRouter(); + +function sakura_options(string $namespace, $default) +{ + $CF = new Sakura\Controllers\ConfigurationController(); + return $CF->sakura_options($namespace, $default); +} diff --git a/app/helpers/setup-helper.php b/app/helpers/setup-helper.php index 93cfd7f..c7db468 100644 --- a/app/helpers/setup-helper.php +++ b/app/helpers/setup-helper.php @@ -2,6 +2,8 @@ namespace Sakura\Helpers; +use Sakura\Controllers\ConfigurationController; + class SetupHelper { public function __construct() @@ -19,6 +21,8 @@ class SetupHelper add_filter('excerpt_length', [$this, 'changes_post_excerpt_length'], 10); // count post views add_action('get_header', [$this, 'set_post_views']); + // Inite config options + add_action('after_switch_theme', [new ConfigurationController(), 'inite_theme'], 1, 2); } public function setup() diff --git a/app/models/option-model.php b/app/models/option-model.php index a4b2971..68a0837 100644 --- a/app/models/option-model.php +++ b/app/models/option-model.php @@ -11,7 +11,7 @@ class OptionModel extends BaseModel return self::$namespace . "_{$key}"; } - public static function create(string $key, $value) + public static function create(string $key, $value) { return add_option(self::the_key($key), $value); } diff --git a/docs/mdc.md b/docs/mdc.md index ae28962..f6226f4 100644 --- a/docs/mdc.md +++ b/docs/mdc.md @@ -1 +1,3 @@ Elevation & shadows: + +Typegraphy: diff --git a/package.json b/package.json index 8b4a559..e3466a8 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "sass": "^1.35.1", "sass-loader": "^12.1.0", "snakecase-keys": "^4.0.2", + "swiper": "^6.7.5", "uuid": "^8.3.2", "vue": "^3.1.4", "vue-intl": "^6.0.6", diff --git a/src/admin/App.vue b/src/admin/App.vue index c69b77d..78e38d4 100644 --- a/src/admin/App.vue +++ b/src/admin/App.vue @@ -1,23 +1,27 @@ diff --git a/src/admin/Layout.vue b/src/admin/Layout.vue deleted file mode 100644 index f250046..0000000 --- a/src/admin/Layout.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - - - diff --git a/src/admin/OptionItem.vue b/src/admin/OptionItem.vue new file mode 100644 index 0000000..6486a2c --- /dev/null +++ b/src/admin/OptionItem.vue @@ -0,0 +1,24 @@ + + + diff --git a/src/admin/api/index.ts b/src/admin/api.ts similarity index 54% rename from src/admin/api/index.ts rename to src/admin/api.ts index fc3f97e..9afad44 100644 --- a/src/admin/api/index.ts +++ b/src/admin/api.ts @@ -1,11 +1,12 @@ import request from '@/utils/http' export default { - postConfigJson(config: any): Promise { + postConfigJson(data: any): Promise { return request({ url: '/sakura/v1/config', method: 'POST', - data: config, + headers: { 'Content-Type': 'application/json' }, + data: data, }) }, } diff --git a/src/admin/styles/index.scss b/src/admin/index.scss similarity index 91% rename from src/admin/styles/index.scss rename to src/admin/index.scss index 8621026..4e4ff14 100644 --- a/src/admin/styles/index.scss +++ b/src/admin/index.scss @@ -11,3 +11,4 @@ @use "@material/tab-scroller/mdc-tab-scroller"; @use "@material/tab-indicator/mdc-tab-indicator"; @use "@material/tab/mdc-tab"; +@use '@material/typography/mdc-typography'; diff --git a/src/admin/main.ts b/src/admin/main.ts index f3ef10c..42eef22 100644 --- a/src/admin/main.ts +++ b/src/admin/main.ts @@ -3,13 +3,13 @@ import { VueSvgIconPlugin } from '@yzfe/vue3-svgicon' import '@yzfe/svgicon/lib/svgicon.css' import App from './App.vue' import { storeProviderPlugin } from '@/hooks/store' -// import { auth, init, posts, comments } from './store' +import store from './store' import { intlPlugin } from '../locales' import UiIcon from '@/components/icon/UiIcon.vue' import Image from '@/components/image/Image.vue' const app = createApp(App) -// app.use(storeProviderPlugin, [auth, init, posts, comments]) +app.use(storeProviderPlugin, [store]) app.use(intlPlugin) app.use(VueSvgIconPlugin, { tagName: 'svg-icon' }) app.component('UiIcon', UiIcon) diff --git a/src/admin/options.ts b/src/admin/options.ts new file mode 100644 index 0000000..46e5698 --- /dev/null +++ b/src/admin/options.ts @@ -0,0 +1,51 @@ +export interface Options { + [tag: string]: { + title: string + icon: string + options: Array<{ + namespace: string + type: string + default: any + }> + } +} + +const options: Options = { + basic: { + title: 'Basic', + icon: 'fas fa-address-card', + options: [ + { + namespace: 'basic.siteTitle', + type: 'string', + default: 'Opps', + }, + { + namespace: 'basic.userName', + type: 'string', + default: 'Mashiro', + }, + ], + }, + social: { + title: 'Social', + icon: 'fas fa-users', + options: [ + { namespace: 'social.github', type: 'string', default: 'mashirozx' }, + { namespace: 'social.weibo', type: 'string', default: 'mashirozx' }, + ], + }, + other: { + title: 'Other', + icon: 'fas fa-umbrella', + options: [ + { + namespace: 'other.hello', + type: 'string', + default: 'world', + }, + ], + }, +} + +export default options diff --git a/src/admin/store.ts b/src/admin/store.ts new file mode 100644 index 0000000..2804224 --- /dev/null +++ b/src/admin/store.ts @@ -0,0 +1,39 @@ +import { Ref } from 'vue' +import { useState } from '@/hooks' +import API from '@/api' +import camelcaseKeys from 'camelcase-keys' +import intl from '@/locales' +import options, { Options } from './options' +import { cloneDeep } from 'lodash' + +export interface OptionStore { + [namespace: string]: any +} + +export default function auth(): object { + const [config, setConfig]: [Ref, (arg: OptionStore) => void] = useState({}) + + const updateOption = (configState: Ref, key: string, value: any) => { + const config = cloneDeep(configState.value) + config[key] = value + setConfig(config) + } + + // const saveOption + // const resetOption + // const resetAllOption + + // const mapOption = (configState: Ref) => { + // const config = cloneDeep(configState.value) + // const data: OptionStore = {} + // Object.keys(options).forEach((tagKey) => { + // const tag = options[tagKey] + // Object.keys(tag.options).forEach((namespace) => { + // data[tagKey][namespace].payload = config[namespace] + // }) + // }) + // return data + // } + + return { config, setConfig } +} diff --git a/src/components/tabBar/TabBar.vue b/src/components/tabBar/TabBar.vue index b3eb0e0..3a29eae 100644 --- a/src/components/tabBar/TabBar.vue +++ b/src/components/tabBar/TabBar.vue @@ -80,4 +80,9 @@ export default defineComponent({ .tab-bar__container { width: 100%; } +.mdc-tab__icon { + font-size: 14px; + width: 14px; + height: 14px; +} diff --git a/yarn.lock b/yarn.lock index 89d92ec..d14c2fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2788,6 +2788,13 @@ dom-serializer@^1.0.1: domhandler "^4.2.0" entities "^2.0.0" +dom7@^3.0.0: + version "3.0.0" + resolved "https://registry.npm.taobao.org/dom7/download/dom7-3.0.0.tgz#b861ce5d67a6becd7aaa3ad02942ff14b1240331" + integrity sha1-uGHOXWemvs16qjrQKUL/FLEkAzE= + dependencies: + ssr-window "^3.0.0-alpha.1" + domelementtype@1: version "1.3.1" resolved "https://registry.npm.taobao.org/domelementtype/download/domelementtype-1.3.1.tgz?cache=0&sync_timestamp=1617298554829&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomelementtype%2Fdownload%2Fdomelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" @@ -6235,6 +6242,11 @@ sprintf-js@~1.0.2: resolved "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +ssr-window@^3.0.0, ssr-window@^3.0.0-alpha.1: + version "3.0.0" + resolved "https://registry.npm.taobao.org/ssr-window/download/ssr-window-3.0.0.tgz#fd5b82801638943e0cc704c4691801435af7ac37" + integrity sha1-/VuCgBY4lD4MxwTEaRgBQ1r3rDc= + stable@^0.1.8: version "0.1.8" resolved "https://registry.npm.taobao.org/stable/download/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -6438,6 +6450,14 @@ svgo@^1.3.2: unquote "~1.1.1" util.promisify "~1.0.0" +swiper@^6.7.5: + version "6.7.5" + resolved "https://registry.nlark.com/swiper/download/swiper-6.7.5.tgz?cache=0&sync_timestamp=1625145077063&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fswiper%2Fdownload%2Fswiper-6.7.5.tgz#8f150c7281919b7d6bea00889e9dc16448e92986" + integrity sha1-jxUMcoGRm31r6gCInp3BZEjpKYY= + dependencies: + dom7 "^3.0.0" + ssr-window "^3.0.0" + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.npm.taobao.org/symbol-tree/download/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"