Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
n8n_ai_assistant
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
n8n_ai_assistant
Commits
fcf8d461
Commit
fcf8d461
authored
Apr 12, 2024
by
Domi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: Sidebar support drag and drop
parent
ac39b82b
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
247 additions
and
164 deletions
+247
-164
Multitasking.vue
src/components/Multitasking.vue
+1
-2
SiteButton.vue
src/components/SiteButton.vue
+2
-7
ChatDocsAddon.vue
src/components/chatdocs/ChatDocsAddon.vue
+2
-1
IconAdd.vue
src/components/icons/IconAdd.vue
+11
-0
ContentSidebar.vue
src/components/sidebar/ContentSidebar.vue
+0
-23
Navbar.vue
src/components/sidebar/Navbar.vue
+212
-0
SidebarHome.vue
src/components/sidebar/SidebarHome.vue
+1
-1
manifest.ts
src/manifest.ts
+1
-1
Dev.vue
src/pages/Dev.vue
+2
-0
Sidebar.vue
src/pages/Sidebar.vue
+15
-129
No files found.
src/components/Multitasking.vue
View file @
fcf8d461
...
@@ -406,9 +406,8 @@ const handleEditCommand = (e: MouseEvent) => {
...
@@ -406,9 +406,8 @@ const handleEditCommand = (e: MouseEvent) => {
text-wrap
:
nowrap
;
text-wrap
:
nowrap
;
}
}
.shortcut
.key
{
.shortcut
.key
{
padding
:
2px
4px
;
border-radius
:
4px
;
background
:
var
(
--color-background-soft
);
background
:
var
(
--color-background-soft
);
@apply
text-xs
uppercase
px-1
py-0.5
rounded;
}
}
@keyframes
fadein
{
@keyframes
fadein
{
...
...
src/components/SiteButton.vue
View file @
fcf8d461
...
@@ -26,6 +26,7 @@ defineEmits(["click", "remove"])
...
@@ -26,6 +26,7 @@ defineEmits(["click", "remove"])
]"
]"
@
click=
"(e) => (e.preventDefault(), $emit('click'))"
@
click=
"(e) => (e.preventDefault(), $emit('click'))"
:href=
"url"
:href=
"url"
draggable=
"true"
>
>
<div
class=
"p-2.5 rounded-full bg-background-soft"
>
<div
class=
"p-2.5 rounded-full bg-background-soft"
>
<img
<img
...
@@ -57,13 +58,7 @@ defineEmits(["click", "remove"])
...
@@ -57,13 +58,7 @@ defineEmits(["click", "remove"])
'size-4 absolute top-[-4px] right-[-4px] opacity-0 group-hover:opacity-65 rounded-full',
'size-4 absolute top-[-4px] right-[-4px] opacity-0 group-hover:opacity-65 rounded-full',
'bg-background-soft hover:bg-red-100 hover:text-red-600 hover:scale-105 flex items-center justify-center',
'bg-background-soft hover:bg-red-100 hover:text-red-600 hover:scale-105 flex items-center justify-center',
]"
]"
@
click=
"
@
click=
"(e) => (e.stopPropagation(), $emit('remove'))"
(e) =>
{
e.stopPropagation()
e.preventDefault()
$emit('remove')
}
"
>
>
<IconClose
class=
"size-3"
/>
<IconClose
class=
"size-3"
/>
</div>
</div>
...
...
src/components/chatdocs/ChatDocsAddon.vue
View file @
fcf8d461
...
@@ -211,4 +211,5 @@ onUnmounted(() => {
...
@@ -211,4 +211,5 @@ onUnmounted(() => {
</div>
</div>
</
template
>
</
template
>
<
style
scoped
></
style
>
@/utils/const
<
style
scoped
></
style
>
\ No newline at end of file
@/utils/const
src/components/icons/IconAdd.vue
0 → 100644
View file @
fcf8d461
<
template
>
<svg
xmlns=
"http://www.w3.org/2000/svg"
height=
"24"
viewBox=
"0 -960 960 960"
width=
"24"
fill=
"currentColor"
>
<path
d=
"M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z"
/>
</svg>
</
template
>
src/components/sidebar/ContentSidebar.vue
View file @
fcf8d461
...
@@ -139,29 +139,6 @@ onUnmounted(() => {
...
@@ -139,29 +139,6 @@ onUnmounted(() => {
@
pointerdown=
"autoPointerCapture"
@
pointerdown=
"autoPointerCapture"
@
pointermove=
"pointermove"
@
pointermove=
"pointermove"
></div>
></div>
<div
v-if=
"false"
class=
"flex gap-2 items-center justify-between h-8 px-2"
>
<button
@
click=
""
class=
"size-7 flex items-center justify-center mr-auto"
>
<img
class=
"size-4"
:src=
"logoUrl"
/>
</button>
<button
@
click=
"emit('hide')"
class=
"size-7 rounded-full hover:bg-background-soft flex items-center justify-center"
>
<IconSplitscreenRight
class=
"size-5 scale-95"
/>
</button>
<button
@
click=
"emit('close')"
class=
"size-7 rounded-full hover:bg-background-soft flex items-center justify-center"
>
<IconClose
class=
"size-5"
/>
</button>
</div>
<iframe
class=
"w-full h-full flex-1"
:src=
"sidebarUrl"
></iframe>
<iframe
class=
"w-full h-full flex-1"
:src=
"sidebarUrl"
></iframe>
</div>
</div>
</div>
</div>
...
...
src/components/sidebar/Navbar.vue
0 → 100644
View file @
fcf8d461
<
script
setup
lang=
"ts"
>
import
{
ref
}
from
"vue"
import
{
homeUrl
}
from
"@/utils/const"
import
{
useI18n
}
from
"@/utils/i18n"
import
{
handleImgError
}
from
"@/utils/dom"
import
{
type
PageInfo
}
from
"../Webview.vue"
import
IconClose
from
"@/components/icons/IconClose.vue"
import
IconRefresh
from
"@/components/icons/IconRefresh.vue"
import
IconPhone
from
"@/components/icons/IconPhone.vue"
import
IconHide
from
"@/components/icons/IconHide.vue"
import
IconNavigateBefore
from
"@/components/icons/IconNavigateBefore.vue"
import
IconNavigateNext
from
"@/components/icons/IconNavigateNext.vue"
import
IconAdd
from
"@/components/icons/IconAdd.vue"
defineProps
<
{
active
:
number
pages
:
{
url
:
string
}[]
pagesInfo
:
(
PageInfo
|
null
)[]
isMobileUA
:
boolean
isPointerIn
:
boolean
closeWebview
?:
(
index
:
number
)
=>
void
reload
?:
()
=>
void
toggleMobileUA
:
()
=>
void
collapseSidebar
?:
()
=>
void
closeSidebar
?:
()
=>
void
goBack
?:
()
=>
void
goForward
?:
()
=>
void
}
>
()
const
emit
=
defineEmits
<
{
switch
:
[
number
]
drop
:
[
string
]
}
>
()
const
{
t
}
=
useI18n
()
const
logoUrl
=
chrome
.
runtime
.
getURL
(
"/logo.svg"
)
const
globeImg
=
chrome
.
runtime
.
getURL
(
"img/globe.svg"
)
let
count
=
0
const
dragActive
=
ref
(
false
)
const
handleDragEnter
=
(
e
:
DragEvent
)
=>
{
count
++
if
(
e
.
dataTransfer
?.
types
.
includes
(
"text/uri-list"
))
{
e
.
preventDefault
()
dragActive
.
value
=
true
}
}
const
handleDragLeave
=
(
e
:
DragEvent
)
=>
{
count
--
if
(
count
<=
0
)
{
dragActive
.
value
=
false
}
console
.
log
(
"count: "
,
count
)
}
const
handleDragOver
=
(
e
:
DragEvent
)
=>
{
if
(
e
.
dataTransfer
?.
types
.
includes
(
"text/uri-list"
))
{
e
.
preventDefault
()
}
}
const
handleDrop
=
(
e
:
DragEvent
)
=>
{
e
.
preventDefault
()
dragActive
.
value
=
false
if
(
!
e
.
dataTransfer
)
{
return
}
const
url
=
e
.
dataTransfer
.
getData
(
"text/uri-list"
)
console
.
log
(
"url: "
,
url
)
emit
(
"drop"
,
url
)
}
</
script
>
<
template
>
<div
:class=
"[
'flex gap-1 items-center justify-between h-9 px-1 z-10 shadow-sm',
'*:size-7 *:flex *:items-center *:justify-center ',
]"
@
dragenter=
"handleDragEnter"
@
dragover=
"handleDragOver"
@
dragleave=
"handleDragLeave"
@
drop=
"handleDrop"
>
<a
draggable=
"true"
@
click=
"(e) => (e.preventDefault(), $emit('switch', -1))"
:href=
"homeUrl"
title=
"Anything Copilot"
:class=
"[
'group rounded-full relative box-border border',
active === -1
? 'bg-primary/10 border-primary-500'
: 'border-transparent hover:bg-background-mute bg-background-soft',
]"
>
<img
:class=
"[
'size-4 group-hover:opacity-85 transition-all pointer-events-none',
false ? 'opacity-85' : 'opacity-50',
]"
:src=
"logoUrl"
/>
<!--
<IconHome
class=
"size-5 group-active:scale-90 transition-transform"
/>
-->
</a>
<a
v-for=
"(page, i) of pages"
draggable=
"true"
@
click=
"(e) => (e.preventDefault(), $emit('switch', i))"
:href=
"pagesInfo[i]?.url"
:title=
"pagesInfo[i]?.title"
:class=
"[
'group rounded-full relative box-border border',
active === i
? 'bg-primary/10 border-primary-500'
: 'border-transparent hover:bg-background-mute bg-background-soft',
]"
>
<img
class=
"size-4 pointer-events-none"
loading=
"lazy"
:src=
"pagesInfo[i]?.icon || globeImg"
:data-fallback=
"globeImg"
@
error=
"handleImgError"
/>
<span
v-if=
"active === i && closeWebview"
class=
"absolute hidden group-hover:block rounded-full bg-primary-500 text-white -top-0.5 -right-0.5 transition-all p-0.5"
@
click=
"
(e) => (e.preventDefault(), e.stopPropagation(), closeWebview?.(i))
"
>
<IconClose
class=
"size-2"
/>
</span>
</a>
<a
v-if=
"dragActive"
class=
"rounded-full box-border border border-primary-500 bg-primary/10 text-primary"
>
<IconAdd
class=
"size-5 group-active:scale-90 transition-transform"
/>
</a>
<span
class=
"mx-auto"
></span>
<button
v-if=
"goBack"
@
click=
"goBack()"
class=
"group hover:bg-background-soft rounded-full"
>
<IconNavigateBefore
class=
"size-5 scale-125 group-active:-translate-x-1 transition-transform"
/>
</button>
<button
v-if=
"goForward"
@
click=
"goForward()"
class=
"group hover:bg-background-soft rounded-full"
>
<IconNavigateNext
class=
"size-5 scale-125 group-active:translate-x-1 transition-transform"
/>
</button>
<button
v-if=
"reload"
@
click=
"reload()"
:title=
"t('refresh')"
class=
"group hover:bg-background-soft rounded-full"
>
<IconRefresh
class=
"size-5 group-active:rotate-180 transition-transform"
/>
</button>
<button
v-if=
"toggleMobileUA"
@
click=
"toggleMobileUA"
:title=
"t('mobileView')"
:class=
"[
'group hover:bg-background-soft rounded-full transition ease-in-out delay-200',
{ 'bg-background-soft text-primary-500 ': isMobileUA },
isPointerIn ? '' : ' opacity-75',
]"
>
<IconPhone
class=
"size-4 group-active:scale-90 transition-transform"
/>
</button>
<button
v-if=
"collapseSidebar"
@
click=
"collapseSidebar()"
:title=
"t('minimize')"
class=
"group hover:bg-background-soft rounded-full"
>
<IconHide
class=
"size-5 scale-95 group-active:scale-90 transition-transform"
/>
</button>
<button
v-if=
"closeSidebar"
@
click=
"closeSidebar()"
:title=
"t('close')"
class=
"group hover:bg-background-soft rounded-full"
>
<IconClose
class=
"size-5 group-active:scale-90 transition-transform"
/>
</button>
</div>
</
template
>
<
style
scoped
></
style
>
src/components/sidebar/SidebarHome.vue
View file @
fcf8d461
...
@@ -22,7 +22,7 @@ const emit = defineEmits({
...
@@ -22,7 +22,7 @@ const emit = defineEmits({
<div
class=
"flex flex-col p-6 w-full max-w-md mx-auto"
>
<div
class=
"flex flex-col p-6 w-full max-w-md mx-auto"
>
<div
class=
"flex flex-col items-center gap-2 mx-auto mt-16"
>
<div
class=
"flex flex-col items-center gap-2 mx-auto mt-16"
>
<img
:src=
"logoUrl"
class=
"size-16"
/>
<img
:src=
"logoUrl"
class=
"size-16"
/>
<span
class=
"text-2xl font-bold my-2"
>
{{
t
(
"sidebar"
)
}}
</span>
<span
class=
"text-2xl font-bold my-2"
>
Anything Copilot
</span>
</div>
</div>
<div
class=
"my-12"
>
<div
class=
"my-12"
>
...
...
src/manifest.ts
View file @
fcf8d461
...
@@ -24,7 +24,7 @@ export const defaultSidebarPath = "sidebar.html"
...
@@ -24,7 +24,7 @@ export const defaultSidebarPath = "sidebar.html"
const
manifest
=
{
const
manifest
=
{
// maximum of 45 characters
// maximum of 45 characters
name
:
"__MSG_name__"
,
name
:
"__MSG_name__"
,
version
:
"1.2.
9
"
,
version
:
"1.2.
10
"
,
// edge 12 characters
// edge 12 characters
// short_name: "__MSG_short_name__",
// short_name: "__MSG_short_name__",
// no more than 132 characters
// no more than 132 characters
...
...
src/pages/Dev.vue
View file @
fcf8d461
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
Webview
from
"@/components/Webview.vue"
import
Webview
from
"@/components/Webview.vue"
import
Multitasking
from
"@/components/Multitasking.vue"
;
</
script
>
</
script
>
<
template
>
<
template
>
<!--
<div
class=
"w-screen h-screen"
>
<!--
<div
class=
"w-screen h-screen"
>
<Webview
url=
"https://github.com"
/>
<Webview
url=
"https://github.com"
/>
</div>
-->
</div>
-->
<Multitasking
/>
</
template
>
</
template
>
<
style
scoped
></
style
>
<
style
scoped
></
style
>
src/pages/Sidebar.vue
View file @
fcf8d461
...
@@ -12,20 +12,9 @@ import Webview, { type PageInfo } from "@/components/Webview.vue"
...
@@ -12,20 +12,9 @@ import Webview, { type PageInfo } from "@/components/Webview.vue"
import
{
useI18n
}
from
"@/utils/i18n"
import
{
useI18n
}
from
"@/utils/i18n"
import
{
MessageType
}
from
"@/types"
import
{
MessageType
}
from
"@/types"
import
SidebarHome
from
"@/components/sidebar/SidebarHome.vue"
import
SidebarHome
from
"@/components/sidebar/SidebarHome.vue"
import
IconClose
from
"@/components/icons/IconClose.vue"
import
Navbar
from
"@/components/sidebar/Navbar.vue"
import
IconSplitscreenRight
from
"@/components/icons/IconSplitscreenRight.vue"
import
IconNavigateBefore
from
"@/components/icons/IconNavigateBefore.vue"
import
IconNavigateNext
from
"@/components/icons/IconNavigateNext.vue"
import
IconRefresh
from
"@/components/icons/IconRefresh.vue"
import
IconHome
from
"@/components/icons/IconHome.vue"
import
IconPhone
from
"@/components/icons/IconPhone.vue"
import
IconHide
from
"@/components/icons/IconHide.vue"
import
{
handleImgError
}
from
"@/utils/dom"
import
{
FrameMessageType
}
from
"@/types"
import
{
FrameMessageType
}
from
"@/types"
import
{
homeUrl
}
from
"@/utils/const"
const
logoUrl
=
chrome
.
runtime
.
getURL
(
"/logo.svg"
)
const
globeImg
=
chrome
.
runtime
.
getURL
(
"img/globe.svg"
)
const
{
t
}
=
useI18n
()
const
{
t
}
=
useI18n
()
const
mobileUA
=
const
mobileUA
=
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"
...
@@ -320,123 +309,20 @@ function handlePointerLeave() {
...
@@ -320,123 +309,20 @@ function handlePointerLeave() {
@
pointerenter=
"handlePointerEnter"
@
pointerenter=
"handlePointerEnter"
@
pointerleave=
"handlePointerLeave"
@
pointerleave=
"handlePointerLeave"
>
>
<div
<Navbar
:class=
"[
:active=
"active"
'flex gap-1 items-center justify-between h-9 px-1 z-10 shadow-sm',
:pages=
"pages"
'*:size-7 *:flex *:items-center *:justify-center ',
:pagesInfo=
"pagesInfo"
]"
:isMobileUA=
"isMobileUA"
>
:isPointerIn=
"isPointerIn"
<a
:closeWebview=
"closeWebview"
@
click=
"(e) => (e.preventDefault(), (active = -1))"
:reload=
"reload"
:href=
"homeUrl"
:toggleMobileUA=
"toggleMobileUA"
title=
"Anything Copilot"
:collapseSidebar=
"mode == 'content' ? collapseSidebar : undefined"
:class=
"[
:closeSidebar=
"mode == 'content' ? closeSidebar : undefined"
'group rounded-full relative box-border border',
@
switch=
"active = $event"
active === -1
@
drop=
"go"
? 'bg-primary/10 border-primary-500'
/>
: 'border-transparent hover:bg-background-mute bg-background-soft',
]"
>
<img
:class=
"[
'size-4 group-hover:opacity-85 transition-all pointer-events-none',
false ? 'opacity-85' : 'opacity-50',
]"
:src=
"logoUrl"
/>
<!--
<IconHome
class=
"size-5 group-active:scale-90 transition-transform"
/>
-->
</a>
<a
v-for=
"(page, i) of pages"
@
click=
"(e) => (e.preventDefault(), (active = i))"
:href=
"pagesInfo[i]?.url"
:title=
"pagesInfo[i]?.title"
:class=
"[
'group rounded-full relative box-border border',
active === i
? 'bg-primary/10 border-primary-500'
: 'border-transparent hover:bg-background-mute bg-background-soft',
]"
>
<img
class=
"size-4 pointer-events-none"
loading=
"lazy"
:src=
"pagesInfo[i]?.icon || globeImg"
:data-fallback=
"globeImg"
@
error=
"handleImgError"
/>
<span
v-if=
"active === i"
class=
"absolute hidden group-hover:block rounded-full bg-primary-500 text-white -top-0.5 -right-0.5 transition-all p-0.5"
@
click=
"
(e) =>
{
e.preventDefault()
e.stopPropagation()
closeWebview(i)
}
"
>
<IconClose
class=
"size-2"
/>
</span>
</a>
<span
class=
"mx-auto"
></span>
<!--
<button
@
click=
"goBack()"
class=
"group hover:bg-background-soft rounded-full"
>
<IconNavigateBefore
class=
"size-5 scale-125 group-active:-translate-x-1 transition-transform"
/>
</button>
<button
@
click=
"goForward()"
class=
"group hover:bg-background-soft rounded-full"
>
<IconNavigateNext
class=
"size-5 scale-125 group-active:translate-x-1 transition-transform"
/>
</button>
-->
<button
@
click=
"reload()"
:title=
"t('refresh')"
class=
"group hover:bg-background-soft rounded-full"
>
<IconRefresh
class=
"size-5 group-active:rotate-180 transition-transform"
/>
</button>
<button
@
click=
"toggleMobileUA"
:title=
"t('mobileView')"
:class=
"[
'group hover:bg-background-soft rounded-full transition ease-in-out delay-200',
{ 'bg-background-soft text-primary-500 ': isMobileUA },
isPointerIn ? '' : ' opacity-75',
]"
>
<IconPhone
class=
"size-4 group-active:scale-90 transition-transform"
/>
</button>
<button
v-if=
"mode == 'content'"
@
click=
"collapseSidebar()"
:title=
"t('minimize')"
class=
"group hover:bg-background-soft rounded-full"
>
<IconHide
class=
"size-5 scale-95 group-active:scale-90 transition-transform"
/>
</button>
<button
v-if=
"mode == 'content'"
@
click=
"closeSidebar()"
:title=
"t('close')"
class=
"group hover:bg-background-soft rounded-full"
>
<IconClose
class=
"size-5 group-active:scale-90 transition-transform"
/>
</button>
</div>
<div
:class=
"['w-full h-full',
{ hidden: active != -1 }]">
<div
:class=
"['w-full h-full',
{ hidden: active != -1 }]">
<SidebarHome
<SidebarHome
...
...
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