Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
cd7000da
Unverified
Commit
cd7000da
authored
Jun 19, 2022
by
STEVEN
Committed by
GitHub
Jun 19, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: responsive view (#75)
* chore: add license * feat: mobile view
parent
b96d78ed
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
149 additions
and
119 deletions
+149
-119
LICENSE
LICENSE
+21
-0
package.json
web/package.json
+1
-2
MemoCardDialog.tsx
web/src/components/MemoCardDialog.tsx
+8
-8
MemoEditor.tsx
web/src/components/MemoEditor.tsx
+1
-1
MemosHeader.tsx
web/src/components/MemosHeader.tsx
+10
-4
SettingDialog.tsx
web/src/components/SettingDialog.tsx
+22
-18
Sidebar.tsx
web/src/components/Sidebar.tsx
+15
-0
api.ts
web/src/helpers/api.ts
+2
-0
app.less
web/src/less/app.less
+0
-2
global.less
web/src/less/global.less
+2
-27
home.less
web/src/less/home.less
+12
-8
memo-card-dialog.less
web/src/less/memo-card-dialog.less
+3
-5
memo-trash-dialog.less
web/src/less/memo-trash-dialog.less
+2
-1
memos-header.less
web/src/less/memos-header.less
+9
-7
menu-btns-popup.less
web/src/less/menu-btns-popup.less
+2
-10
mixin.less
web/src/less/mixin.less
+0
-4
search-bar.less
web/src/less/search-bar.less
+1
-2
setting-dialog.less
web/src/less/setting-dialog.less
+15
-10
my-account-section.less
web/src/less/settings/my-account-section.less
+4
-2
siderbar.less
web/src/less/siderbar.less
+13
-2
signin.less
web/src/less/signin.less
+1
-1
Home.tsx
web/src/pages/Home.tsx
+4
-4
tsconfig.json
web/tsconfig.json
+1
-1
No files found.
LICENSE
0 → 100644
View file @
cd7000da
MIT License
Copyright (c) 2022 Memos
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
web/package.json
View file @
cd7000da
...
...
@@ -33,6 +33,5 @@
"tailwindcss"
:
"^3.0.18"
,
"typescript"
:
"^4.3.2"
,
"vite"
:
"^2.9.0"
},
"license"
:
"MIT"
}
}
web/src/components/MemoCardDialog.tsx
View file @
cd7000da
...
...
@@ -150,11 +150,11 @@ const MemoCardDialog: React.FC<Props> = (props: Props) => {
{
linkMemos
.
length
>
0
?
(
<
div
className=
"linked-memos-wrapper"
>
<
p
className=
"normal-text"
>
{
linkMemos
.
length
}
related MEMO
</
p
>
{
linkMemos
.
map
((
m
)
=>
{
const
rawtext
=
parseHtmlToRawText
(
formatMemoContent
(
m
.
content
)).
replaceAll
(
"
\n
"
,
" "
);
{
linkMemos
.
map
((
m
emo
,
index
)
=>
{
const
rawtext
=
parseHtmlToRawText
(
formatMemoContent
(
m
emo
.
content
)).
replaceAll
(
"
\n
"
,
" "
);
return
(
<
div
className=
"linked-memo-container"
key=
{
m
.
id
}
onClick=
{
()
=>
handleLinkedMemoClick
(
m
)
}
>
<
span
className=
"time-text"
>
{
m
.
dateStr
}
</
span
>
<
div
className=
"linked-memo-container"
key=
{
`${index}-${memo.id}`
}
onClick=
{
()
=>
handleLinkedMemoClick
(
memo
)
}
>
<
span
className=
"time-text"
>
{
m
emo
.
dateStr
}
</
span
>
{
rawtext
}
</
div
>
);
...
...
@@ -164,11 +164,11 @@ const MemoCardDialog: React.FC<Props> = (props: Props) => {
{
linkedMemos
.
length
>
0
?
(
<
div
className=
"linked-memos-wrapper"
>
<
p
className=
"normal-text"
>
{
linkedMemos
.
length
}
linked MEMO
</
p
>
{
linkedMemos
.
map
((
m
)
=>
{
const
rawtext
=
parseHtmlToRawText
(
formatMemoContent
(
m
.
content
)).
replaceAll
(
"
\n
"
,
" "
);
{
linkedMemos
.
map
((
m
emo
,
index
)
=>
{
const
rawtext
=
parseHtmlToRawText
(
formatMemoContent
(
m
emo
.
content
)).
replaceAll
(
"
\n
"
,
" "
);
return
(
<
div
className=
"linked-memo-container"
key=
{
m
.
id
}
onClick=
{
()
=>
handleLinkedMemoClick
(
m
)
}
>
<
span
className=
"time-text"
>
{
m
.
dateStr
}
</
span
>
<
div
className=
"linked-memo-container"
key=
{
`${index}-${memo.id}`
}
onClick=
{
()
=>
handleLinkedMemoClick
(
memo
)
}
>
<
span
className=
"time-text"
>
{
m
emo
.
dateStr
}
</
span
>
{
rawtext
}
</
div
>
);
...
...
web/src/components/MemoEditor.tsx
View file @
cd7000da
...
...
@@ -294,7 +294,7 @@ const MemoEditor: React.FC<Props> = () => {
/>
<
div
ref=
{
tagSeletorRef
}
className=
{
`tag-list ${isTagSeletorShown && tags.length > 0 ? "" : "hidden"}`
}
className=
{
`tag-list ${isTagSeletorShown && tags.length > 0 ? "" : "
!
hidden"}`
}
onClick=
{
handleTagSeletorClick
}
>
{
tags
.
map
((
t
)
=>
{
...
...
web/src/components/MemosHeader.tsx
View file @
cd7000da
import
{
useCallback
,
useEffect
,
useState
}
from
"react"
;
import
{
memoService
,
shortcutService
}
from
"../services"
;
import
{
useAppSelector
}
from
"../store"
;
import
SearchBar
from
"./SearchBar"
;
import
{
memoService
,
shortcutService
}
from
"../services
"
;
import
{
toggleSiderbar
}
from
"./Sidebar
"
;
import
"../less/memos-header.less"
;
let
prevRequestTimestamp
=
Date
.
now
();
...
...
@@ -25,7 +26,7 @@ const MemosHeader: React.FC<Props> = () => {
}
},
[
query
,
shortcuts
]);
const
handle
Memo
TextClick
=
useCallback
(()
=>
{
const
handle
Title
TextClick
=
useCallback
(()
=>
{
const
now
=
Date
.
now
();
if
(
now
-
prevRequestTimestamp
>
10
*
1000
)
{
prevRequestTimestamp
=
now
;
...
...
@@ -37,8 +38,13 @@ const MemosHeader: React.FC<Props> = () => {
return
(
<
div
className=
"section-header-container memos-header-container"
>
<
div
className=
"title-text"
onClick=
{
handleMemoTextClick
}
>
<
span
className=
"normal-text"
>
{
titleText
}
</
span
>
<
div
className=
"title-container"
>
<
div
className=
"action-btn"
onClick=
{
toggleSiderbar
}
>
<
img
src=
"/icons/menu.svg"
className=
"icon-img"
alt=
""
/>
</
div
>
<
span
className=
"title-text"
onClick=
{
handleTitleTextClick
}
>
{
titleText
}
</
span
>
</
div
>
<
SearchBar
/>
</
div
>
...
...
web/src/components/SettingDialog.tsx
View file @
cd7000da
...
...
@@ -34,27 +34,31 @@ const SettingDialog: React.FC<Props> = (props: Props) => {
</
button
>
<
div
className=
"section-selector-container"
>
<
span
className=
"section-title"
>
Basic
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"my-account"
)
}
className=
{
`section-item ${state.selectedSection === "my-account" ? "selected" : ""}`
}
>
My account
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"preferences"
)
}
className=
{
`section-item ${state.selectedSection === "preferences" ? "selected" : ""}`
}
>
Preferences
</
span
>
<
div
className=
"section-items-container"
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"my-account"
)
}
className=
{
`section-item ${state.selectedSection === "my-account" ? "selected" : ""}`
}
>
My account
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"preferences"
)
}
className=
{
`section-item ${state.selectedSection === "preferences" ? "selected" : ""}`
}
>
Preferences
</
span
>
</
div
>
{
user
?.
role
===
"OWNER"
?
(
<>
<
span
className=
"section-title"
>
Admin
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"member"
)
}
className=
{
`section-item ${state.selectedSection === "member" ? "selected" : ""}`
}
>
Member
</
span
>
<
div
className=
"section-items-container"
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"member"
)
}
className=
{
`section-item ${state.selectedSection === "member" ? "selected" : ""}`
}
>
Member
</
span
>
</
div
>
</>
)
:
null
}
</
div
>
...
...
web/src/components/Sidebar.tsx
View file @
cd7000da
...
...
@@ -27,6 +27,11 @@ const Sidebar: React.FC<Props> = () => {
return
(
<
aside
className=
"sidebar-wrapper"
>
<
div
className=
"close-container"
>
<
span
className=
"action-btn"
onClick=
{
toggleSiderbar
}
>
<
img
src=
"/icons/close.svg"
className=
"icon-img"
alt=
""
/>
</
span
>
</
div
>
<
UserBanner
/>
<
div
className=
"status-text-container"
>
<
div
className=
"status-text memos-text"
>
...
...
@@ -57,4 +62,14 @@ const Sidebar: React.FC<Props> = () => {
);
};
export
const
toggleSiderbar
=
()
=>
{
const
sidebarEl
=
document
.
body
.
querySelector
(
".sidebar-wrapper"
)
as
HTMLDivElement
;
const
display
=
window
.
getComputedStyle
(
sidebarEl
).
display
;
if
(
display
===
"none"
)
{
sidebarEl
.
style
.
display
=
"flex"
;
}
else
{
sidebarEl
.
style
.
display
=
"none"
;
}
};
export
default
Sidebar
;
web/src/helpers/api.ts
View file @
cd7000da
import
axios
from
"axios"
;
axios
.
defaults
.
withCredentials
=
true
;
type
ResponseObject
<
T
>
=
{
data
:
T
;
error
?:
string
;
...
...
web/src/less/app.less
View file @
cd7000da
@import "./mixin.less";
#root {
.flex(row, flex-start, flex-start);
@apply w-full h-full;
}
web/src/less/global.less
View file @
cd7000da
@import "./mixin.less";
* {
@apply m-0 p-0 box-border;
color: @text-black;
-webkit-tap-highlight-color: transparent;
}
body,
html {
@apply
w-screen h-screen overflow-hidden
text-base;
@apply text-base;
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans", "Noto Sans CJK SC", "Microsoft YaHei UI", "Microsoft YaHei",
"WenQuanYi Micro Hei", sans-serif, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
"Noto Color Emoji";
}
code {
@apply bg-pink-600 p-1 rounded font-mono;
}
pre {
@apply font-mono;
* {
@apply font-mono;
}
}
label,
button,
img {
...
...
@@ -57,17 +39,10 @@ li {
}
a {
@apply cursor-pointer text-blue-600 underline underline-offset-2;
&:hover {
@apply opacity-80;
}
@apply cursor-pointer text-blue-600 underline underline-offset-2 hover:opacity-80;
}
.btn {
@apply select-none cursor-pointer text-center;
}
.hidden {
display: none !important;
}
web/src/less/home.less
View file @
cd7000da
@import "./mixin.less";
@import "./memos-header.less";
#root {
.page-wrapper.home {
@apply relative top-0 w-full h-screen overflow-y-auto;
background-color: #f6f5f4;
}
#page-wrapper {
@apply w-full h-full m-auto grid max-w-4xl mx-auto;
grid-template-columns: min-content 1fr;
> .page-container {
@apply relative w-full min-h-screen mx-auto flex flex-row justify-center items-start;
>.sidebar-wrapper{
@apply flex-shrink-0;
}
> .memos-wrapper {
@apply relative w-full max-w-2xl min-h-full overflow-x-hidden flex flex-col justify-start items-start px-4 sm:pr-6;
.memos-wrapper {
@apply w-full h-full overflow-x-hidden flex flex-col justify-start items-start px-4 pr-10;
}
}
}
web/src/less/memo-card-dialog.less
View file @
cd7000da
@import "./mixin.less";
.dialog-wrapper.memo-card-dialog {
> .dialog-container {
@apply p-0 bg-transparent;
@apply px-4;
> * {
@apply shrink-0;
}
> .dialog-container {
@apply w-full p-0 bg-transparent flex flex-col justify-start items-center;
> .memo-card-container {
.flex(column, flex-start, flex-start);
...
...
web/src/less/memo-trash-dialog.less
View file @
cd7000da
@import "./mixin.less";
@import "./memos-header.less";
.memo-trash-dialog {
@apply px-4;
> .dialog-container {
@apply w-128 max-w-full mb-8;
...
...
web/src/less/memos-header.less
View file @
cd7000da
...
...
@@ -5,20 +5,22 @@
.flex(row, space-between, center);
@apply w-full h-10 flex-nowrap mt-4 mb-2 shrink-0;
> .title-text {
.flex(row, flex-start, center);
@apply font-bold text-lg leading-10 mr-2 text-ellipsis shrink-0 cursor-pointer overflow-hidden;
color: @text-black;
> .title-container {
@apply flex flex-row justify-start items-center mr-2 shrink-0 overflow-hidden;
> .action-btn {
.flex(row, center, center);
@apply w-6 h-6 mr-1 shrink-0;
@apply flex sm:hidden flex-row justify-center items-center w-6 h-6 mr-1 shrink-0;
background-color: unset;
> .icon-img {
@apply w-
4
h-auto;
@apply w-
5
h-auto;
}
}
> .title-text {
@apply font-bold text-lg leading-10 mr-2 text-ellipsis shrink-0 cursor-pointer overflow-hidden;
color: @text-black;
}
}
> .btns-container {
...
...
web/src/less/menu-btns-popup.less
View file @
cd7000da
...
...
@@ -2,22 +2,14 @@
.menu-btns-popup {
.flex(column, flex-start, flex-start);
@apply absolute mt-1 ml-24 p-1 w-44 rounded-lg z-10 shadow bg-white;
&:hover {
display: flex;
}
@apply absolute right-0 top-0 mt-1 p-1 w-36 rounded-lg z-10 shadow bg-white;
> .btn {
.flex(row, flex-start, center);
@apply w-full py-2 px-3 text-base rounded text-left;
@apply w-full py-2 px-3 text-base rounded text-left
hover:bg-gray-100
;
> .icon {
@apply block w-6 text-center mr-2 text-base;
}
&:hover {
background-color: @bg-whitegray;
}
}
}
web/src/less/mixin.less
View file @
cd7000da
...
...
@@ -15,10 +15,6 @@
@bg-light-blue: #eef3fe;
@bg-paper-yellow: #fbf4de;
.mono-font-family {
font-family: SFMono-Regular, Menlo, Consolas, "PT Mono", "Liberation Mono", Courier, monospace;
}
.hide-scroll-bar {
.pretty-scroll-bar(0, 0);
...
...
web/src/less/search-bar.less
View file @
cd7000da
...
...
@@ -23,8 +23,7 @@
}
> .quickly-action-wrapper {
@apply hidden absolute top-9 -right-2 p-2 w-80;
z-index: 2;
@apply hidden absolute top-9 -right-2 p-2 w-80 z-10;
> .quickly-action-container {
.flex(column, flex-start, flex-start);
...
...
web/src/less/setting-dialog.less
View file @
cd7000da
@import "./mixin.less";
@import "./memos-header.less";
.setting-dialog {
@apply px-4;
> .dialog-container {
@apply w-176 max-w-full mb-8 p-0;
> .dialog-content-container {
.flex(column, flex-start, flex-start);
@apply relative w-full overflow-y-scroll p-0 flex flex-row justify-start items-start;
@apply relative w-full overflow-y-scroll p-0 flex flex-
col sm:flex-
row justify-start items-start;
.hide-scroll-bar();
> .close-btn {
...
...
@@ -20,23 +21,28 @@
}
> .section-selector-container {
@apply w-
40 h-full shrink-0
rounded-l-lg p-4 border-r bg-gray-100 flex flex-col justify-start items-start;
@apply w-
full sm:w-40 h-auto sm:h-full shrink-0 rounded-t-lg sm:
rounded-l-lg p-4 border-r bg-gray-100 flex flex-col justify-start items-start;
> .section-title {
@apply text-sm mt-4 first:mt-3 mb-1 font-mono text-gray-400;
}
>
.section-item
{
@apply
text-base left-6 mt-2 text-gray-700 cursor-pointer hover:opacity-80
;
>
.section-items-container
{
@apply
w-full h-auto flex flex-row sm:flex-col justify-start items-start
;
&.selected {
@apply font-bold hover:opacity-100;
> .section-item {
@apply text-base mr-2 sm:mr-0 mt-2 text-gray-700 cursor-pointer hover:opacity-80;
&.selected {
@apply font-bold hover:opacity-100;
}
}
}
}
> .section-content-container {
@apply w-auto p-4 px-6 grow flex flex-col justify-start items-start h-128 overflow-y-scroll;
@apply w-
full sm:w-
auto p-4 px-6 grow flex flex-col justify-start items-start h-128 overflow-y-scroll;
> .section-container {
.flex(column, flex-start, flex-start);
...
...
@@ -47,8 +53,7 @@
}
> .form-label {
.flex(row, flex-start, center);
@apply w-full mb-2;
@apply flex flex-row justify-start items-center w-full mb-2;
> .normal-text {
@apply shrink-0 select-text;
...
...
web/src/less/settings/my-account-section.less
View file @
cd7000da
...
...
@@ -9,12 +9,14 @@
}
&.username-label {
@apply w-full flex-wrap;
> input {
@apply grow-0 shadow-inner w-auto px-2 py-1 text-base border rounded leading-6 bg-transparent focus:border-black;
@apply grow-0 shadow-inner w-auto px-2 py-1
mr-2
text-base border rounded leading-6 bg-transparent focus:border-black;
}
> .btns-container {
@apply m
l
-2 shrink-0 flex flex-row justify-start items-center;
@apply m
r
-2 shrink-0 flex flex-row justify-start items-center;
> .btn {
@apply text-sm shadow px-4 py-1 leading-6 rounded border hover:opacity-80 bg-gray-50;
...
...
web/src/less/siderbar.less
View file @
cd7000da
@import "./mixin.less";
.sidebar-wrapper {
.flex(column, flex-start, flex-start);
@apply w-64 h-full py-4 pl-2 overflow-x-hidden overflow-y-auto;
@apply fixed sm:sticky top-0 left-0 hidden sm:!flex flex-col justify-start items-start w-64 h-screen py-4 pl-2 z-10 bg-white sm:bg-transparent shadow-2xl sm:shadow-none overflow-x-hidden overflow-y-auto transition-all;
.hide-scroll-bar();
> .close-container {
@apply w-full pr-6 my-2 flex sm:hidden flex-row justify-end items-center;
> .action-btn {
@apply p-1 bg-gray-100 rounded shadow;
> .icon-img {
@apply w-4 h-auto;
}
}
}
> .action-btns-container {
@apply w-full px-2 my-2 flex flex-col justify-start items-start shrink-0;
...
...
web/src/less/signin.less
View file @
cd7000da
...
...
@@ -2,7 +2,7 @@
.page-wrapper.signin {
.flex(row, center, center);
@apply w-full
h-full
bg-white;
@apply w-full
min-h-screen
bg-white;
> .page-container {
@apply w-80 max-w-full py-4 -mt-16;
...
...
web/src/pages/Home.tsx
View file @
cd7000da
...
...
@@ -32,9 +32,9 @@ function Home() {
},
[]);
return
(
<>
<
section
className=
"page-wrapper home"
>
{
loadingState
.
isLoading
?
null
:
(
<
section
id=
"page-wrapp
er"
>
<
div
className=
"page-contain
er"
>
<
Sidebar
/>
<
main
className=
"memos-wrapper"
>
<
MemosHeader
/>
...
...
@@ -42,9 +42,9 @@ function Home() {
<
MemoFilter
/>
<
MemoList
/>
</
main
>
</
section
>
</
div
>
)
}
</>
</
section
>
);
}
...
...
web/tsconfig.json
View file @
cd7000da
...
...
@@ -16,5 +16,5 @@
"noEmit"
:
true
,
"jsx"
:
"react-jsx"
},
"include"
:
[
"./src"
,
"./public"
]
"include"
:
[
"./src"
]
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment