ShortcutsModal.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import React from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import { Modal, ModalHeader, ModalBody } from 'reactstrap';
  4. import { useShortcutsModal } from '~/stores/modal';
  5. import styles from './ShortcutsModal.module.scss';
  6. const ShortcutsModal = (): JSX.Element => {
  7. const { t } = useTranslation();
  8. const { data: status, close } = useShortcutsModal();
  9. const bodyContent = () => {
  10. if (status == null || !status.isOpened) {
  11. return <></>;
  12. }
  13. // add classes to cmd-key by OS
  14. const platform = window.navigator.platform.toLowerCase();
  15. const isMac = (platform.indexOf('mac') > -1);
  16. const additionalClassByOs = isMac ? 'mac' : 'win';
  17. return (
  18. <div className="container">
  19. <div className="row">
  20. <div className="col-lg-6">
  21. <h6>
  22. <strong>{t('modal_shortcuts.global.title')}</strong>
  23. </h6>
  24. <ul className="list-unstyled m-0">
  25. {/* Open/Close shortcut help */}
  26. <li className="d-flex align-items-center p-3 border-bottom">
  27. <div className="flex-grow-1">
  28. <span
  29. className="text-nowrap"
  30. // eslint-disable-next-line react/no-danger
  31. dangerouslySetInnerHTML={{ __html: t('modal_shortcuts.global.Open/Close shortcut help') }}
  32. />
  33. </div>
  34. <div className="d-flex align-items-center">
  35. <span className={`key cmd-key ${additionalClassByOs}`}></span>
  36. <span className="text-secondary mx-2">+</span>
  37. <span className="key">/</span>
  38. </div>
  39. </li>
  40. {/* Create Page */}
  41. <li className="d-flex align-items-center p-3 border-bottom">
  42. <div className="flex-grow-1">{t('modal_shortcuts.global.Create Page')}</div>
  43. <div>
  44. <span className="key">C</span>
  45. </div>
  46. </li>
  47. {/* Edit Page */}
  48. <li className="d-flex align-items-center p-3 border-bottom">
  49. <div className="flex-grow-1">{t('modal_shortcuts.global.Edit Page')}</div>
  50. <div>
  51. <span className="key">E</span>
  52. </div>
  53. </li>
  54. {/* Search */}
  55. <li className="d-flex align-items-center p-3 border-bottom">
  56. <div className="flex-grow-1">{t('modal_shortcuts.global.Search')}</div>
  57. <div>
  58. <span className="key">/</span>
  59. </div>
  60. </li>
  61. {/* Show Contributors */}
  62. <li className="d-flex align-items-center p-3 border-bottom">
  63. <div className="flex-grow-1">
  64. <span
  65. className="text-nowrap"
  66. // eslint-disable-next-line react/no-danger
  67. dangerouslySetInnerHTML={{ __html: t('modal_shortcuts.global.Show Contributors') }}
  68. />
  69. </div>
  70. <div className="text-start">
  71. <a href={t('modal_shortcuts.global.konami_code_url')} target="_blank" rel="noreferrer">
  72. <span className="text-secondary small">
  73. {t('modal_shortcuts.global.Konami Code')}
  74. </span>
  75. </a>
  76. <div className="d-flex gap-2 flex-column align-items-start mt-1">
  77. <div className="d-flex gap-1">
  78. <span className="key material-symbols-outlined fs-5 px-0">arrow_upward</span>
  79. <span className="key material-symbols-outlined fs-5 px-0">arrow_upward</span>
  80. <span className="key material-symbols-outlined fs-5 px-0">arrow_downward</span>
  81. <span className="key material-symbols-outlined fs-5 px-0">arrow_downward</span>
  82. </div>
  83. <div className="d-flex gap-1">
  84. <span className="key material-symbols-outlined fs-5 px-0">arrow_back</span>
  85. <span className="key material-symbols-outlined fs-5 px-0">arrow_forward</span>
  86. <span className="key material-symbols-outlined fs-5 px-0">arrow_back</span>
  87. <span className="key material-symbols-outlined fs-5 px-0">arrow_forward</span>
  88. </div>
  89. <div className="d-flex gap-1">
  90. <span className="key">B</span>
  91. <span className="key">A</span>
  92. </div>
  93. </div>
  94. </div>
  95. </li>
  96. {/* Mirror Mode */}
  97. <li className="d-flex align-items-center p-3">
  98. <div className="flex-grow-1">{t('modal_shortcuts.global.MirrorMode')}</div>
  99. <div className="text-start">
  100. <a href={t('modal_shortcuts.global.konami_code_url')} target="_blank" rel="noreferrer">
  101. <span className="text-secondary small">
  102. {t('modal_shortcuts.global.Konami Code')}
  103. </span>
  104. </a>
  105. <div className="d-flex gap-2 flex-column align-items-start mt-1">
  106. <div className="d-flex gap-1">
  107. <span className="key">X</span>
  108. <span className="key">X</span>
  109. <span className="key">B</span>
  110. <span className="key">B</span>
  111. </div>
  112. <div className="d-flex gap-1">
  113. <span className="key">A</span>
  114. <span className="key">Y</span>
  115. <span className="key">A</span>
  116. <span className="key">Y</span>
  117. </div>
  118. <div className="d-flex gap-1">
  119. <span className="key material-symbols-outlined fs-5 px-0">arrow_downward</span>
  120. <span className="key material-symbols-outlined fs-5 px-0">arrow_back</span>
  121. </div>
  122. </div>
  123. </div>
  124. </li>
  125. </ul>
  126. </div>
  127. <div className="col-lg-6">
  128. <h6>
  129. <strong>{t('modal_shortcuts.editor.title')}</strong>
  130. </h6>
  131. <ul className="list-unstyled m-0">
  132. {/* Search in Editor */}
  133. <li className="d-flex align-items-center p-3 border-bottom">
  134. <div className="flex-grow-1">{t('modal_shortcuts.editor.Search in Editor')}</div>
  135. <div className="text-nowrap">
  136. <span className={`key cmd-key ${additionalClassByOs}`}></span>
  137. <span className="text-secondary mx-2">+</span>
  138. <span className="key">F</span>
  139. </div>
  140. </li>
  141. {/* Save Page */}
  142. <li className="d-flex align-items-center p-3 border-bottom">
  143. <div className="flex-grow-1">
  144. {t('modal_shortcuts.editor.Save Page')}
  145. <span className="small text-secondary ms-1">{t('modal_shortcuts.editor.Only Editor')}</span>
  146. </div>
  147. <div className="text-nowrap">
  148. <span className={`key cmd-key ${additionalClassByOs}`}></span>
  149. <span className="text-secondary mx-2">+</span>
  150. <span className="key">S</span>
  151. </div>
  152. </li>
  153. {/* Indent */}
  154. <li className="d-flex align-items-center p-3 border-bottom">
  155. <div className="flex-grow-1">{t('modal_shortcuts.editor.Indent')}</div>
  156. <div>
  157. <span className="key">Tab</span>
  158. </div>
  159. </li>
  160. {/* Outdent */}
  161. <li className="d-flex align-items-center p-3 border-bottom">
  162. <div className="flex-grow-1">{t('modal_shortcuts.editor.Outdent')}</div>
  163. <div className="text-nowrap gap-1">
  164. <span className="key">Shift</span>
  165. <span className="text-secondary mx-2">+</span>
  166. <span className="key">Tab</span>
  167. </div>
  168. </li>
  169. {/* Delete Line */}
  170. <li className="d-flex align-items-center p-3 border-bottom">
  171. <div className="flex-grow-1">{t('modal_shortcuts.editor.Delete Line')}</div>
  172. <div className="text-nowrap">
  173. <span className={`key cmd-key ${additionalClassByOs}`}></span>
  174. <span className="text-secondary mx-2">+</span>
  175. <span className="key">Shift</span>
  176. <span className="text-secondary mx-2">+</span>
  177. <span className="key">K</span>
  178. </div>
  179. </li>
  180. {/* Insert Line */}
  181. <li className="d-flex align-items-center p-3 border-bottom">
  182. <div className="flex-grow-1">
  183. <span
  184. // eslint-disable-next-line react/no-danger
  185. dangerouslySetInnerHTML={{ __html: t('modal_shortcuts.editor.Insert Line') }}
  186. />
  187. <br />
  188. <span className="small text-secondary ms-1">{t('modal_shortcuts.editor.Post Comment')}</span>
  189. </div>
  190. <div className="text-nowrap">
  191. <span className={`key cmd-key ${additionalClassByOs}`}></span>
  192. <span className="text-secondary mx-2">+</span>
  193. <span className="key">Enter</span>
  194. </div>
  195. </li>
  196. {/* Move Line */}
  197. <li className="d-flex align-items-center p-3 border-bottom">
  198. <div className="flex-grow-1">{t('modal_shortcuts.editor.Move Line')}</div>
  199. <div className="text-nowrap">
  200. <span className={`key alt-key ${additionalClassByOs}`}></span>
  201. <span className="text-secondary mx-2">+</span>
  202. <span className="key material-symbols-outlined fs-5 px-0">arrow_downward</span>
  203. <span className="text-secondary mx-2">or</span>
  204. <span className="key material-symbols-outlined fs-5 px-0">arrow_upward</span>
  205. </div>
  206. </li>
  207. {/* Copy Line */}
  208. <li className="d-flex align-items-center p-3 border-bottom">
  209. <div className="flex-grow-1">{t('modal_shortcuts.editor.Copy Line')}</div>
  210. <div className="text-nowrap">
  211. <div className="text-start">
  212. <div>
  213. <span className={`key alt-key ${additionalClassByOs}`}></span>
  214. <span className="text-secondary mx-2">+</span>
  215. <span className="key">Shift</span>
  216. <span className="text-secondary ms-2">+</span>
  217. </div>
  218. <div className="mt-1">
  219. <span className="key material-symbols-outlined fs-5 px-0">arrow_downward</span>
  220. <span className="text-secondary mx-2">or</span>
  221. <span className="key material-symbols-outlined fs-5 px-0">arrow_upward</span>
  222. </div>
  223. </div>
  224. </div>
  225. </li>
  226. {/* Toggle Line */}
  227. <li className="d-flex align-items-center p-3">
  228. <div className="flex-grow-1">{t('modal_shortcuts.editor.Toggle Line')}</div>
  229. <div className="text-nowrap">
  230. <span className={`key cmd-key ${additionalClassByOs}`}></span>
  231. <span className="text-secondary mx-2">+</span>
  232. <span className="key">/</span>
  233. </div>
  234. </li>
  235. </ul>
  236. </div>
  237. {/* TODO: Add docs link button https://redmine.weseek.co.jp/issues/161862 */}
  238. </div>
  239. </div>
  240. );
  241. };
  242. return (
  243. <>
  244. { status != null && (
  245. <Modal id="shortcuts-modal" size="lg" isOpen={status.isOpened} toggle={close} className={`shortcuts-modal ${styles['shortcuts-modal']}`}>
  246. <ModalHeader tag="h4" toggle={close} className="px-4">
  247. {t('Shortcuts')}
  248. </ModalHeader>
  249. <ModalBody className="p-md-4">
  250. {bodyContent()}
  251. </ModalBody>
  252. </Modal>
  253. ) }
  254. </>
  255. );
  256. };
  257. export default ShortcutsModal;