Skip to content

Commit cc30208

Browse files
xinyouyuerlibuzualex4506
authored andcommitted
Add files via upload
1 parent 7b78ecc commit cc30208

18 files changed

+648
-0
lines changed

100243383/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/png" href="/aptos.png" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Aptos todo list boilerplate</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>

100243383/move/Move.toml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = 'my_todo_list'
3+
version = '1.0.0'
4+
[dependencies.AptosFramework]
5+
git = 'https://gitee.com/WGB5445/aptos-core.git'
6+
rev = 'mainnet'
7+
subdir = 'aptos-move/framework/aptos-framework'
8+
[addresses]
9+
todolist_addr="_"

100243383/move/sources/wishlist.move

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
module todolist_addr::todolist {
2+
3+
use aptos_framework::account;
4+
use aptos_framework::event;
5+
use std::signer;
6+
use std::vector;
7+
use std::string::String;
8+
9+
10+
const E_NOT_INITIALIZED: u64 = 1;
11+
const ETASK_DOESNT_EXIST: u64 = 2;
12+
const ETASK_IS_COMPLETED: u64 = 3;
13+
14+
struct TodoList has key {
15+
tasks: vector<Task>,
16+
set_task_event: event::EventHandle<Task>,
17+
}
18+
19+
struct Task has store, drop, copy {
20+
address:address,
21+
content: String,
22+
completed: bool,
23+
}
24+
25+
public entry fun create_list(account: &signer){
26+
let wish_list = TodoList {
27+
tasks: vector::empty(),
28+
set_task_event: account::new_event_handle<Task>(account),
29+
};
30+
31+
move_to(account, wish_list);
32+
}
33+
34+
public entry fun create_task(account: &signer, content: String) acquires TodoList {
35+
36+
let signer_address = signer::address_of(account);
37+
38+
assert!(exists<TodoList>(signer_address), E_NOT_INITIALIZED);
39+
40+
let wish_list = borrow_global_mut<TodoList>(signer_address);
41+
42+
let new_task = Task {
43+
address: signer_address,
44+
content,
45+
completed: false
46+
};
47+
48+
let length = vector::length(&wish_list.tasks);
49+
vector::insert(&mut wish_list.tasks, length, new_task);
50+
51+
event::emit_event<Task>(
52+
&mut borrow_global_mut<TodoList>(signer_address).set_task_event,
53+
new_task,
54+
);
55+
}
56+
57+
public entry fun complete_task(account: &signer, task_id: u64) acquires TodoList {
58+
59+
let signer_address = signer::address_of(account);
60+
61+
assert!(exists<TodoList>(signer_address), E_NOT_INITIALIZED);
62+
63+
let wish_list = borrow_global_mut<TodoList>(signer_address);
64+
65+
assert!(task_id < vector::length(&wish_list.tasks), ETASK_DOESNT_EXIST);
66+
67+
let task_record = vector::borrow_mut(&mut wish_list.tasks, task_id);
68+
69+
assert!(task_record.completed == false, ETASK_IS_COMPLETED);
70+
71+
task_record.completed = true;
72+
}
73+
}

100243383/public/aptos.png

8.5 KB
Loading

100243383/src/App.tsx

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// wallet adapter
2+
import { AptosWalletAdapterProvider } from "@aptos-labs/wallet-adapter-react";
3+
// wallets
4+
import { PetraWallet } from "petra-plugin-wallet-adapter";
5+
import { PontemWallet } from "@pontem/wallet-adapter-plugin";
6+
import { MartianWallet } from "@martianwallet/aptos-wallet-adapter";
7+
import { RiseWallet } from "@rise-wallet/wallet-adapter";
8+
import { FewchaWallet } from "fewcha-plugin-wallet-adapter";
9+
import { MSafeWalletAdapter } from "msafe-plugin-wallet-adapter";
10+
import { NightlyWallet } from "@nightlylabs/aptos-wallet-adapter-plugin";
11+
import { OpenBlockWallet } from "@openblockhq/aptos-wallet-adapter";
12+
import { TokenPocketWallet } from "@tp-lab/aptos-wallet-adapter";
13+
import { TrustWallet } from "@trustwallet/aptos-wallet-adapter";
14+
import { WelldoneWallet } from "@welldone-studio/aptos-wallet-adapter";
15+
16+
import Header from "./components/Header";
17+
import Content from "./components/Content";
18+
import { useAlert } from "./hooks/alertProvider";
19+
20+
const wallets = [
21+
new PetraWallet(),
22+
new PontemWallet(),
23+
new RiseWallet(),
24+
new FewchaWallet(),
25+
new MartianWallet(),
26+
new MSafeWalletAdapter(),
27+
new NightlyWallet(),
28+
new OpenBlockWallet(),
29+
new TokenPocketWallet(),
30+
new TrustWallet(),
31+
new WelldoneWallet(),
32+
];
33+
34+
function App() {
35+
const { setErrorAlertMessage } = useAlert();
36+
37+
return (
38+
<AptosWalletAdapterProvider
39+
plugins={wallets}
40+
autoConnect={true}
41+
onError={(error) => {
42+
console.log("Custom error handling", error);
43+
setErrorAlertMessage(error);
44+
}}
45+
>
46+
<div>Hope you pass my homework.Thank you!</div>
47+
<Header />
48+
<Content />
49+
</AptosWalletAdapterProvider>
50+
51+
);
52+
53+
}
54+
55+
56+
export default App;

100243383/src/abi.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const ABI = {"address":"0x8f838ee41b0cc142e46dfeac5a68e50be1488594b91ca8eefd17682e8e86c3f2","name":"todolist","friends":[],"exposed_functions":[{"name":"complete_task","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer","u64"],"return":[]},{"name":"create_list","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer"],"return":[]},{"name":"create_task","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer","0x1::string::String"],"return":[]}],"structs":[{"name":"Task","is_native":false,"abilities":["copy","drop","store"],"generic_type_params":[],"fields":[{"name":"address","type":"address"},{"name":"content","type":"0x1::string::String"},{"name":"completed","type":"bool"}]},{"name":"TodoList","is_native":false,"abilities":["key"],"generic_type_params":[],"fields":[{"name":"tasks","type":"vector<0x8f838ee41b0cc142e46dfeac5a68e50be1488594b91ca8eefd17682e8e86c3f2::todolist::Task>"},{"name":"set_task_event","type":"0x1::event::EventHandle<0x8f838ee41b0cc142e46dfeac5a68e50be1488594b91ca8eefd17682e8e86c3f2::todolist::Task>"}]}]} as const

100243383/src/components/Alert.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Alert } from "antd";
2+
import { Dispatch, ReactNode, SetStateAction } from "react";
3+
4+
type Alert = {
5+
text: ReactNode;
6+
setText: Dispatch<SetStateAction<ReactNode | null>>;
7+
};
8+
9+
export function SuccessAlert({ text }: Alert) {
10+
return <Alert message={text} type="success" closable />;
11+
}
12+
13+
export function ErrorAlert({ text }: Alert) {
14+
return <Alert message={text} type="error" closable />;
15+
}

100243383/src/components/Content.tsx

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { useWallet } from "@aptos-labs/wallet-adapter-react";
2+
import { Spin } from "antd";
3+
import { useCallback, useEffect, useState } from "react";
4+
import { aptos } from "../utils/consts";
5+
import { Task } from "../utils/types";
6+
import ListView from "../views/ListView";
7+
import NoListView from "../views/NoListView";
8+
import { ABI } from "../abi";
9+
10+
export default function Content() {
11+
const [tasks, setTasks] = useState<Task[]>([]);
12+
13+
const { account } = useWallet();
14+
const accountAddr: `0x${string}` | null = account
15+
? account.address.startsWith("0x")
16+
? (account.address as `0x${string}`)
17+
: `0x${account.address}`
18+
: null;
19+
const [accountHasList, setAccountHasList] = useState<boolean>(false);
20+
const [transactionInProgress, setTransactionInProgress] =
21+
useState<boolean>(false);
22+
23+
const fetchList = useCallback(async () => {
24+
if (!accountAddr) return [];
25+
try {
26+
const todoListResource = await aptos.getAccountResource({
27+
accountAddress: accountAddr,
28+
resourceType: `${ABI.address}::todolist::TodoList`,
29+
});
30+
setAccountHasList(true);
31+
setTasks(todoListResource.tasks as Task[]);
32+
} catch (e: any) {
33+
setAccountHasList(false);
34+
}
35+
}, [accountAddr]);
36+
37+
useEffect(() => {
38+
fetchList();
39+
}, [account?.address, fetchList]);
40+
41+
return (
42+
<Spin spinning={transactionInProgress}>
43+
{!accountHasList ? (
44+
<NoListView
45+
setTransactionInProgress={setTransactionInProgress}
46+
setAccountHasList={setAccountHasList}
47+
/>
48+
) : (
49+
<ListView
50+
setTransactionInProgress={setTransactionInProgress}
51+
tasks={tasks}
52+
setTasks={setTasks}
53+
/>
54+
)}
55+
</Spin>
56+
);
57+
}

100243383/src/components/Header.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { WalletSelector } from "@aptos-labs/wallet-adapter-ant-design";
2+
import "@aptos-labs/wallet-adapter-ant-design/dist/index.css";
3+
import { Layout, Row, Col } from "antd";
4+
5+
export default function Header() {
6+
return (
7+
<Layout>
8+
<Row align="middle">
9+
<Col span={10} offset={2}>
10+
<h1>Bucket List</h1>
11+
</Col>
12+
<Col span={12} style={{ textAlign: "right", paddingRight: "200px" }}>
13+
<WalletSelector />
14+
</Col>
15+
</Row>
16+
</Layout>
17+
);
18+
}
+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { useWallet } from "@aptos-labs/wallet-adapter-react";
2+
import { Col, Input, Button } from "antd";
3+
import { useState } from "react";
4+
import { ABI } from "../abi";
5+
import { useAlert } from "../hooks/alertProvider";
6+
import { provider } from "../utils/consts";
7+
import { Task } from "../utils/types";
8+
9+
type TaskInputProps = {
10+
setTransactionInProgress: React.Dispatch<React.SetStateAction<boolean>>;
11+
tasks: Task[];
12+
setTasks: React.Dispatch<React.SetStateAction<Task[]>>;
13+
};
14+
15+
export default function TaskInput({
16+
setTransactionInProgress,
17+
tasks,
18+
setTasks,
19+
}: TaskInputProps) {
20+
const [newTask, setNewTask] = useState<string>("");
21+
const { account, network, signAndSubmitTransaction } = useWallet();
22+
const { setSuccessAlertHash } = useAlert();
23+
24+
const onWriteTask = (event: React.ChangeEvent<HTMLInputElement>) => {
25+
const value = event.target.value;
26+
setNewTask(value);
27+
};
28+
29+
const onTaskAdded = async () => {
30+
// check for connected account
31+
if (!account) return;
32+
setTransactionInProgress(true);
33+
// hold the latest task.task_id from our local state
34+
35+
// build a newTaskToPush objct into our local state
36+
const newTaskToPush = {
37+
address: account.address,
38+
completed: false,
39+
content: newTask,
40+
};
41+
42+
try {
43+
// sign and submit transaction to chain
44+
const response = await signAndSubmitTransaction({
45+
type: "entry_function_payload",
46+
function: `${ABI.address}::todolist::create_task`,
47+
type_arguments: [],
48+
arguments: [newTask],
49+
});
50+
// wait for transaction
51+
await provider.waitForTransaction(response.hash);
52+
setSuccessAlertHash(response.hash, network?.name);
53+
// Create a new array based on current state:
54+
let newTasks = [...tasks];
55+
56+
// Add item to the tasks array
57+
newTasks.push(newTaskToPush);
58+
// Set state
59+
setTasks(newTasks);
60+
// clear input text
61+
setNewTask("");
62+
} catch (error: any) {
63+
console.log("error", error);
64+
} finally {
65+
setTransactionInProgress(false);
66+
}
67+
};
68+
69+
return (
70+
<Col span={8} offset={8}>
71+
<Input.Group compact>
72+
<Input
73+
onChange={(event) => onWriteTask(event)}
74+
style={{ width: "calc(100% - 60px)" }}
75+
placeholder="Add a Wish"
76+
size="large"
77+
value={newTask}
78+
/>
79+
<Button
80+
onClick={onTaskAdded}
81+
type="primary"
82+
style={{ height: "40px", backgroundColor: "#38c536" }}
83+
>
84+
Add
85+
</Button>
86+
</Input.Group>
87+
</Col>
88+
);
89+
}

0 commit comments

Comments
 (0)