Skip to content

Commit 2e70573

Browse files
Merge branch 'master' into npm-dev-20250820
2 parents 422a973 + 3e752b9 commit 2e70573

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1244
-388
lines changed

src/packages/frontend/chat/message.tsx

Lines changed: 115 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Badge, Button, Col, Popconfirm, Row, Space, Tooltip } from "antd";
99
import { List, Map } from "immutable";
1010
import { CSSProperties, useEffect, useLayoutEffect } from "react";
1111
import { useIntl } from "react-intl";
12+
1213
import { Avatar } from "@cocalc/frontend/account/avatar/avatar";
1314
import {
1415
CSS,
@@ -19,6 +20,7 @@ import {
1920
useTypedRedux,
2021
} from "@cocalc/frontend/app-framework";
2122
import { Gap, Icon, TimeAgo, Tip } from "@cocalc/frontend/components";
23+
import CopyButton from "@cocalc/frontend/components/copy-button";
2224
import MostlyStaticMarkdown from "@cocalc/frontend/editors/slate/mostly-static-markdown";
2325
import { IS_TOUCH } from "@cocalc/frontend/feature";
2426
import { modelToName } from "@cocalc/frontend/frame-editors/llm/llm-selector";
@@ -501,14 +503,122 @@ export default function Message({
501503
);
502504
}
503505

504-
function renderMessageBody({ lighten, message_class }) {
505-
const value = newest_content(message);
506+
function renderCopyMessageButton() {
507+
return (
508+
<Tip
509+
placement={"top"}
510+
title={intl.formatMessage({
511+
id: "chat.message.copy_markdown.tooltip",
512+
defaultMessage: "Copy message as markdown",
513+
description:
514+
"Tooltip for button to copy chat message as markdown text",
515+
})}
516+
>
517+
<CopyButton
518+
value={message_to_markdown(message)}
519+
size="small"
520+
noText={true}
521+
style={{
522+
color: is_viewers_message ? "white" : "#888",
523+
fontSize: "12px",
524+
marginTop: "-4px",
525+
}}
526+
/>
527+
</Tip>
528+
);
529+
}
530+
531+
function renderLinkMessageButton() {
532+
return (
533+
<Tip
534+
placement={"top"}
535+
title={intl.formatMessage({
536+
id: "chat.message.copy_link.tooltip",
537+
defaultMessage: "Select message. Copy URL to link to this message.",
538+
description:
539+
"Tooltip for button to copy URL link to specific chat message",
540+
})}
541+
>
542+
<Button
543+
onClick={() => {
544+
actions?.setFragment(message.get("date"));
545+
}}
546+
size="small"
547+
type={"text"}
548+
style={{
549+
color: is_viewers_message ? "white" : "#888",
550+
fontSize: "12px",
551+
marginTop: "-4px",
552+
}}
553+
>
554+
<Icon name="link" />
555+
</Button>
556+
</Tip>
557+
);
558+
}
559+
560+
function renderLLMFeedbackButtons() {
561+
if (isLLMThread) return;
506562

507563
const feedback = message.getIn(["feedback", account_id]);
508564
const otherFeedback =
509565
isLLMThread && msgWrittenByLLM ? 0 : (message.get("feedback")?.size ?? 0);
510566
const showOtherFeedback = otherFeedback > 0;
511567

568+
return (
569+
<Tip
570+
placement={"top"}
571+
title={
572+
!showOtherFeedback
573+
? "Like this"
574+
: () => {
575+
return (
576+
<div>
577+
{Object.keys(message.get("feedback")?.toJS() ?? {}).map(
578+
(account_id) => (
579+
<div key={account_id} style={{ marginBottom: "2px" }}>
580+
<Avatar size={24} account_id={account_id} />{" "}
581+
<User account_id={account_id} />
582+
</div>
583+
),
584+
)}
585+
</div>
586+
);
587+
}
588+
}
589+
>
590+
<Button
591+
style={{
592+
color: !feedback && is_viewers_message ? "white" : "#888",
593+
fontSize: "12px",
594+
marginTop: "-4px",
595+
...(feedback ? {} : { position: "relative", top: "-5px" }),
596+
}}
597+
size="small"
598+
type={feedback ? "dashed" : "text"}
599+
onClick={() => {
600+
actions?.feedback(message, feedback ? null : "positive");
601+
}}
602+
>
603+
{showOtherFeedback ? (
604+
<Badge count={otherFeedback} color="darkblue" size="small" />
605+
) : (
606+
""
607+
)}
608+
<Icon
609+
name="thumbs-up"
610+
style={{
611+
color: showOtherFeedback ? "darkblue" : undefined,
612+
}}
613+
/>
614+
</Button>
615+
</Tip>
616+
);
617+
}
618+
619+
function renderMessageBody({ lighten, message_class }) {
620+
const value = newest_content(message);
621+
512622
return (
513623
<>
514624
<span style={lighten}>
@@ -518,81 +628,9 @@ export default function Message({
518628
align="baseline"
519629
style={{ float: "right", marginRight: "10px" }}
520630
>
521-
{!isLLMThread && (
522-
<Tip
523-
placement={"top"}
524-
title={
525-
!showOtherFeedback
526-
? "Like this"
527-
: () => {
528-
return (
529-
<div>
530-
{Object.keys(
531-
message.get("feedback")?.toJS() ?? {},
532-
).map((account_id) => (
533-
<div
534-
key={account_id}
535-
style={{ marginBottom: "2px" }}
536-
>
537-
<Avatar size={24} account_id={account_id} />{" "}
538-
<User account_id={account_id} />
539-
</div>
540-
))}
541-
</div>
542-
);
543-
}
544-
}
545-
>
546-
<Button
547-
style={{
548-
color: !feedback && is_viewers_message ? "white" : "#888",
549-
fontSize: "12px",
550-
marginTop: "-4px",
551-
...(feedback ? {} : { position: "relative", top: "-5px" }),
552-
}}
553-
size="small"
554-
type={feedback ? "dashed" : "text"}
555-
onClick={() => {
556-
actions?.feedback(message, feedback ? null : "positive");
557-
}}
558-
>
559-
{showOtherFeedback ? (
560-
<Badge
561-
count={otherFeedback}
562-
color="darkblue"
563-
size="small"
564-
/>
565-
) : (
566-
""
567-
)}
568-
<Icon
569-
name="thumbs-up"
570-
style={{
571-
color: showOtherFeedback ? "darkblue" : undefined,
572-
}}
573-
/>
574-
</Button>
575-
</Tip>
576-
)}
577-
<Tip
578-
placement={"top"}
579-
title="Select message. Copy URL to link to this message."
580-
>
581-
<Button
582-
onClick={() => {
583-
actions?.setFragment(message.get("date"));
584-
}}
585-
size="small"
586-
type={"text"}
587-
style={{
588-
color: is_viewers_message ? "white" : "#888",
589-
fontSize: "12px",
590-
marginTop: "-4px",
591-
}}
592-
>
593-
<Icon name="link" />
594-
</Button>
595-
</Tip>
631+
{renderLLMFeedbackButtons()}
632+
{renderCopyMessageButton()}
633+
{renderLinkMessageButton()}
596634
</Space>
597635
</span>
598636
<MostlyStaticMarkdown

src/packages/frontend/compute/google-cloud-config.tsx

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
1-
import type {
2-
Images,
3-
State,
4-
GoogleCloudConfiguration as GoogleCloudConfigurationType,
5-
ComputeServerTemplate,
6-
GoogleCloudAcceleratorType,
7-
} from "@cocalc/util/db-schema/compute-servers";
8-
import { reloadImages, useImages, useGoogleImages } from "./images-hook";
9-
import { GOOGLE_CLOUD_DEFAULTS } from "@cocalc/util/db-schema/compute-servers";
10-
import {
11-
getMinDiskSizeGb,
12-
getArchitecture,
13-
} from "@cocalc/util/db-schema/compute-servers";
141
import {
152
Alert,
163
Button,
@@ -25,44 +12,60 @@ import {
2512
Tooltip,
2613
Typography,
2714
} from "antd";
28-
import { currency, cmp, plural } from "@cocalc/util/misc";
15+
import { isEqual } from "lodash";
16+
import { useEffect, useState } from "react";
17+
18+
import { useTypedRedux } from "@cocalc/frontend/app-framework";
19+
import { A } from "@cocalc/frontend/components/A";
20+
import ShowError from "@cocalc/frontend/components/error";
21+
import { Icon } from "@cocalc/frontend/components/icon";
22+
import Disk from "@cocalc/frontend/compute/cloud/common/disk";
23+
import DNS from "@cocalc/frontend/compute/cloud/common/dns";
24+
import Template from "@cocalc/frontend/compute/cloud/common/template";
25+
import { displayAcceleratorType } from "@cocalc/frontend/compute/cloud/google-cloud/accelerator";
26+
import Specs, {
27+
RamAndCpu,
28+
} from "@cocalc/frontend/compute/cloud/google-cloud/specs";
29+
import ExcludeFromSync from "@cocalc/frontend/compute/exclude-from-sync";
30+
import { filterOption } from "@cocalc/frontend/compute/util";
2931
import computeCost, {
30-
GoogleCloudData,
31-
EXTERNAL_IP_COST,
32-
DATA_TRANSFER_OUT_COST_PER_GiB,
33-
markup,
3432
computeAcceleratorCost,
35-
computeInstanceCost,
3633
computeDiskCost,
34+
computeInstanceCost,
35+
DATA_TRANSFER_OUT_COST_PER_GiB,
36+
EXTERNAL_IP_COST,
37+
GoogleCloudData,
38+
markup,
3739
} from "@cocalc/util/compute/cloud/google-cloud/compute-cost";
40+
import type {
41+
Architecture,
42+
ComputeServerTemplate,
43+
GoogleCloudAcceleratorType,
44+
GoogleCloudConfiguration as GoogleCloudConfigurationType,
45+
Images,
46+
State,
47+
} from "@cocalc/util/db-schema/compute-servers";
48+
import {
49+
getArchitecture,
50+
getMachineTypeArchitecture,
51+
getMinDiskSizeGb,
52+
GOOGLE_CLOUD_DEFAULTS,
53+
} from "@cocalc/util/db-schema/compute-servers";
54+
import { cmp, currency, plural } from "@cocalc/util/misc";
55+
import AllowCollaboratorControl from "./allow-collaborator-control";
3856
import {
3957
getGoogleCloudPriceData,
4058
setImageTested,
4159
setServerConfiguration,
4260
} from "./api";
43-
import { useEffect, useState } from "react";
44-
import { A } from "@cocalc/frontend/components/A";
45-
import { Icon } from "@cocalc/frontend/components/icon";
46-
import { isEqual } from "lodash";
47-
import { useTypedRedux } from "@cocalc/frontend/app-framework";
48-
import SelectImage, { ImageLinks, ImageDescription } from "./select-image";
49-
import Ephemeral from "./ephemeral";
5061
import AutoRestart from "./auto-restart";
51-
import AllowCollaboratorControl from "./allow-collaborator-control";
62+
import { availableClouds } from "./config";
63+
import CostOverview from "./cost-overview";
64+
import Ephemeral from "./ephemeral";
65+
import { reloadImages, useGoogleImages, useImages } from "./images-hook";
5266
import NestedVirtualization from "./nested-virtualization";
53-
import ShowError from "@cocalc/frontend/components/error";
5467
import Proxy from "./proxy";
55-
import CostOverview from "./cost-overview";
56-
import Disk from "@cocalc/frontend/compute/cloud/common/disk";
57-
import DNS from "@cocalc/frontend/compute/cloud/common/dns";
58-
import ExcludeFromSync from "@cocalc/frontend/compute/exclude-from-sync";
59-
import { availableClouds } from "./config";
60-
import Template from "@cocalc/frontend/compute/cloud/common/template";
61-
import Specs, {
62-
RamAndCpu,
63-
} from "@cocalc/frontend/compute/cloud/google-cloud/specs";
64-
import { displayAcceleratorType } from "@cocalc/frontend/compute/cloud/google-cloud/accelerator";
65-
import { filterOption } from "@cocalc/frontend/compute/util";
68+
import SelectImage, { ImageDescription, ImageLinks } from "./select-image";
6669

6770
export const SELECTOR_WIDTH = "350px";
6871

@@ -794,9 +797,7 @@ function Provisioning({ priceData, setConfig, configuration, disabled }) {
794797
</Radio.Button>
795798
<Radio.Button value="standard">
796799
Standard{" "}
797-
{prices != null
798-
? `${currency(prices.standard)}/hour`
799-
: undefined}{" "}
800+
{prices != null ? `${currency(prices.standard)}/hour` : undefined}{" "}
800801
</Radio.Button>
801802
</Radio.Group>
802803
<div style={{ color: "#666", marginTop: "5px" }}>
@@ -939,17 +940,19 @@ function Zone({ priceData, setConfig, configuration, disabled }) {
939940
}
940941

941942
function MachineType({ priceData, setConfig, configuration, disabled, state }) {
942-
const [archType, setArchType] = useState<"x86_64" | "arm64">(
943+
const [archType, setArchType] = useState<Architecture>(
943944
getArchitecture(configuration),
944945
);
945946
const [sortByPrice, setSortByPrice] = useState<boolean>(true);
946947
const [newMachineType, setNewMachineType] = useState<string>(
947948
configuration.machineType ?? "",
948949
);
950+
949951
useEffect(() => {
950952
setNewMachineType(configuration.machineType);
951953
setArchType(getArchitecture(configuration));
952954
}, [configuration.machineType]);
955+
953956
useEffect(() => {
954957
if (archType == "arm64" && getArchitecture(configuration) != "arm64") {
955958
setNewMachineType("t2a-standard-4");
@@ -964,17 +967,19 @@ function MachineType({ priceData, setConfig, configuration, disabled, state }) {
964967
}, [archType, configuration.machineType]);
965968

966969
const machineTypes = Object.keys(priceData.machineTypes);
967-
let allOptions = machineTypes
970+
const allOptions = machineTypes
968971
.filter((machineType) => {
969972
const { acceleratorType } = configuration;
970973
if (!acceleratorType) {
971974
if (machineType.startsWith("g") || machineType.startsWith("a")) {
972975
return false;
973976
}
974-
if (archType == "arm64" && getArchitecture(configuration) != "arm64") {
977+
// Check if the machine type's architecture matches the selected architecture
978+
const machineArch = getMachineTypeArchitecture(machineType);
979+
if (archType == "arm64" && machineArch != "arm64") {
975980
return false;
976981
}
977-
if (archType == "x86_64" && getArchitecture(configuration) == "arm64") {
982+
if (archType == "x86_64" && machineArch != "x86_64") {
978983
return false;
979984
}
980985
} else {
@@ -1049,8 +1054,8 @@ function MachineType({ priceData, setConfig, configuration, disabled, state }) {
10491054
(state ?? "deprovisioned") != "deprovisioned"
10501055
? "Can only be changed when machine is deprovisioned"
10511056
: archType == "x86_64"
1052-
? "Intel or AMD X86_64 architecture machines"
1053-
: "ARM64 architecture machines"
1057+
? "Intel or AMD X86_64 architecture machines"
1058+
: "ARM64 architecture machines"
10541059
}
10551060
>
10561061
<Radio.Group

0 commit comments

Comments
 (0)