mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
Merge branch 'staging' of https://github.com/mazeincoding/AppCut into staging
This commit is contained in:
@@ -80,25 +80,25 @@ export function StickersView() {
|
|||||||
<Separator className="my-4" />
|
<Separator className="my-4" />
|
||||||
<TabsContent
|
<TabsContent
|
||||||
value="all"
|
value="all"
|
||||||
className="p-5 pt-0 mt-0 flex-1 flex flex-col min-h-0"
|
className="px-3 pt-0 mt-0 flex-1 flex flex-col min-h-0"
|
||||||
>
|
>
|
||||||
<StickersContentView category="all" />
|
<StickersContentView category="all" />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent
|
<TabsContent
|
||||||
value="general"
|
value="general"
|
||||||
className="p-5 pt-0 mt-0 flex-1 flex flex-col min-h-0"
|
className="px-3 pt-0 mt-0 flex-1 flex flex-col min-h-0"
|
||||||
>
|
>
|
||||||
<StickersContentView category="general" />
|
<StickersContentView category="general" />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent
|
<TabsContent
|
||||||
value="brands"
|
value="brands"
|
||||||
className="p-5 pt-0 mt-0 flex-1 flex flex-col min-h-0"
|
className="px-3 pt-0 mt-0 flex-1 flex flex-col min-h-0"
|
||||||
>
|
>
|
||||||
<StickersContentView category="brands" />
|
<StickersContentView category="brands" />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent
|
<TabsContent
|
||||||
value="emoji"
|
value="emoji"
|
||||||
className="p-5 pt-0 mt-0 flex-1 flex flex-col min-h-0"
|
className="px-3 pt-0 mt-0 flex-1 flex flex-col min-h-0"
|
||||||
>
|
>
|
||||||
<StickersContentView category="emoji" />
|
<StickersContentView category="emoji" />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
@@ -111,16 +111,22 @@ function StickerGrid({
|
|||||||
icons,
|
icons,
|
||||||
onAdd,
|
onAdd,
|
||||||
addingSticker,
|
addingSticker,
|
||||||
|
capSize = false,
|
||||||
}: {
|
}: {
|
||||||
icons: string[];
|
icons: string[];
|
||||||
onAdd: (iconName: string) => void;
|
onAdd: (iconName: string) => void;
|
||||||
addingSticker: string | null;
|
addingSticker: string | null;
|
||||||
|
capSize?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="grid gap-2"
|
className="grid gap-2"
|
||||||
style={{
|
style={{
|
||||||
gridTemplateColumns: "repeat(auto-fill, 112px)",
|
gridTemplateColumns: capSize
|
||||||
|
? "repeat(auto-fill, minmax(var(--sticker-min, 96px), var(--sticker-max, 160px)))"
|
||||||
|
: "repeat(auto-fit, minmax(var(--sticker-min, 96px), 1fr))",
|
||||||
|
["--sticker-min" as any]: "96px",
|
||||||
|
...(capSize ? ({ ["--sticker-max"]: "160px" } as any) : {}),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{icons.map((iconName) => (
|
{icons.map((iconName) => (
|
||||||
@@ -129,6 +135,7 @@ function StickerGrid({
|
|||||||
iconName={iconName}
|
iconName={iconName}
|
||||||
onAdd={onAdd}
|
onAdd={onAdd}
|
||||||
isAdding={addingSticker === iconName}
|
isAdding={addingSticker === iconName}
|
||||||
|
capSize={capSize}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -148,7 +155,7 @@ function CollectionGrid({
|
|||||||
onSelectCollection: (prefix: string) => void;
|
onSelectCollection: (prefix: string) => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 gap-2 h-full overflow-hidden">
|
<div className="grid grid-cols-1 gap-2">
|
||||||
{collections.map((collection) => (
|
{collections.map((collection) => (
|
||||||
<CollectionItem
|
<CollectionItem
|
||||||
key={collection.prefix}
|
key={collection.prefix}
|
||||||
@@ -198,6 +205,7 @@ function StickersContentView({ category }: { category: StickerCategory }) {
|
|||||||
searchStickers,
|
searchStickers,
|
||||||
downloadSticker,
|
downloadSticker,
|
||||||
clearRecentStickers,
|
clearRecentStickers,
|
||||||
|
setSelectedCategory,
|
||||||
} = useStickersStore();
|
} = useStickersStore();
|
||||||
|
|
||||||
const [addingSticker, setAddingSticker] = useState<string | null>(null);
|
const [addingSticker, setAddingSticker] = useState<string | null>(null);
|
||||||
@@ -363,7 +371,15 @@ function StickersContentView({ category }: { category: StickerCategory }) {
|
|||||||
setSelectedCollection(null);
|
setSelectedCollection(null);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
placeholder="Search icons..."
|
placeholder={
|
||||||
|
category === "all"
|
||||||
|
? "Search all stickers"
|
||||||
|
: category === "general"
|
||||||
|
? "Search icons"
|
||||||
|
: category === "brands"
|
||||||
|
? "Search brands"
|
||||||
|
: "Search Emojis"
|
||||||
|
}
|
||||||
value={localSearchQuery}
|
value={localSearchQuery}
|
||||||
onChange={setLocalSearchQuery}
|
onChange={setLocalSearchQuery}
|
||||||
/>
|
/>
|
||||||
@@ -401,6 +417,7 @@ function StickersContentView({ category }: { category: StickerCategory }) {
|
|||||||
icons={recentStickers.slice(0, 12)}
|
icons={recentStickers.slice(0, 12)}
|
||||||
onAdd={handleAddSticker}
|
onAdd={handleAddSticker}
|
||||||
addingSticker={addingSticker}
|
addingSticker={addingSticker}
|
||||||
|
capSize
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -442,12 +459,32 @@ function StickersContentView({ category }: { category: StickerCategory }) {
|
|||||||
icons={iconsToDisplay}
|
icons={iconsToDisplay}
|
||||||
onAdd={handleAddSticker}
|
onAdd={handleAddSticker}
|
||||||
addingSticker={addingSticker}
|
addingSticker={addingSticker}
|
||||||
|
capSize
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
) : searchQuery ? (
|
) : searchQuery ? (
|
||||||
|
<div className="flex flex-col items-center justify-center py-8 gap-3">
|
||||||
<EmptyView
|
<EmptyView
|
||||||
message={`No stickers found for "${searchQuery}"`}
|
message={`No stickers found for "${searchQuery}"`}
|
||||||
/>
|
/>
|
||||||
|
{category !== "all" && (
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => {
|
||||||
|
const q = localSearchQuery || searchQuery;
|
||||||
|
if (q) {
|
||||||
|
setSearchQuery(q);
|
||||||
|
}
|
||||||
|
setSelectedCategory("all");
|
||||||
|
if (q) {
|
||||||
|
searchStickers(q);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Search in all icons
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -525,9 +562,10 @@ interface StickerItemProps {
|
|||||||
iconName: string;
|
iconName: string;
|
||||||
onAdd: (iconName: string) => void;
|
onAdd: (iconName: string) => void;
|
||||||
isAdding?: boolean;
|
isAdding?: boolean;
|
||||||
|
capSize?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function StickerItem({ iconName, onAdd, isAdding }: StickerItemProps) {
|
function StickerItem({ iconName, onAdd, isAdding, capSize = false }: StickerItemProps) {
|
||||||
const [imageError, setImageError] = useState(false);
|
const [imageError, setImageError] = useState(false);
|
||||||
const [hostIndex, setHostIndex] = useState(0);
|
const [hostIndex, setHostIndex] = useState(0);
|
||||||
|
|
||||||
@@ -561,6 +599,11 @@ function StickerItem({ iconName, onAdd, isAdding }: StickerItemProps) {
|
|||||||
width={64}
|
width={64}
|
||||||
height={64}
|
height={64}
|
||||||
className="w-full h-full object-contain"
|
className="w-full h-full object-contain"
|
||||||
|
style={
|
||||||
|
capSize
|
||||||
|
? { maxWidth: "var(--sticker-max, 160px)", maxHeight: "var(--sticker-max, 160px)" }
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
onError={() => {
|
onError={() => {
|
||||||
const next = hostIndex + 1;
|
const next = hostIndex + 1;
|
||||||
if (next < ICONIFY_HOSTS.length) {
|
if (next < ICONIFY_HOSTS.length) {
|
||||||
@@ -598,6 +641,7 @@ function StickerItem({ iconName, onAdd, isAdding }: StickerItemProps) {
|
|||||||
rounded={true}
|
rounded={true}
|
||||||
variant="card"
|
variant="card"
|
||||||
className=""
|
className=""
|
||||||
|
containerClassName="w-full"
|
||||||
isDraggable={false}
|
isDraggable={false}
|
||||||
/>
|
/>
|
||||||
{isAdding && (
|
{isAdding && (
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export interface DraggableMediaItemProps {
|
|||||||
onAddToTimeline?: (currentTime: number) => void;
|
onAddToTimeline?: (currentTime: number) => void;
|
||||||
aspectRatio?: number;
|
aspectRatio?: number;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
containerClassName?: string;
|
||||||
showPlusOnDrag?: boolean;
|
showPlusOnDrag?: boolean;
|
||||||
showLabel?: boolean;
|
showLabel?: boolean;
|
||||||
rounded?: boolean;
|
rounded?: boolean;
|
||||||
@@ -36,6 +37,7 @@ export function DraggableMediaItem({
|
|||||||
onAddToTimeline,
|
onAddToTimeline,
|
||||||
aspectRatio = 16 / 9,
|
aspectRatio = 16 / 9,
|
||||||
className = "",
|
className = "",
|
||||||
|
containerClassName,
|
||||||
showPlusOnDrag = true,
|
showPlusOnDrag = true,
|
||||||
showLabel = true,
|
showLabel = true,
|
||||||
rounded = true,
|
rounded = true,
|
||||||
@@ -95,7 +97,10 @@ export function DraggableMediaItem({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{variant === "card" ? (
|
{variant === "card" ? (
|
||||||
<div ref={dragRef} className="relative group w-28 h-28">
|
<div
|
||||||
|
ref={dragRef}
|
||||||
|
className={cn("relative group", containerClassName ?? "w-28 h-28")}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className={`flex flex-col gap-1 p-0 h-auto w-full relative cursor-default ${className}`}
|
className={`flex flex-col gap-1 p-0 h-auto w-full relative cursor-default ${className}`}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user