Skip to content

Commit 6bbc861

Browse files
committed
ktl-1123 feat: new main page why kotlin block
1 parent 1390432 commit 6bbc861

19 files changed

+479
-19
lines changed
File renamed without changes.
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import kotlinx.coroutines.*
2+
3+
suspend fun main() { // A function that can be suspended and resumed later
4+
val start = System.currentTimeMillis()
5+
coroutineScope { // Create a scope for starting coroutines
6+
for (i in 1..10) {
7+
launch { // Start 10 concurrent tasks
8+
delay(3000L - i * 300) // Pause their execution
9+
log(start, "Countdown: $i")
10+
}
11+
}
12+
}
13+
// Execution continues when all coroutines in the scope have finished
14+
log(start, "Liftoff!")
15+
}
16+
17+
fun log(start: Long, msg: String) {
18+
println("$msg " +
19+
"(on ${Thread.currentThread().name}) " +
20+
"after ${(System.currentTimeMillis() - start)/1000F}s")
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
fun main() {
2+
// Who sent the most messages?
3+
val frequentSender = messages
4+
.groupBy(Message::sender)
5+
.maxByOrNull { (_, messages) -> messages.size }
6+
?.key // Get their names
7+
println(frequentSender) // [Ma]
8+
9+
// Who are the senders?
10+
val senders = messages
11+
.asSequence() // Make operations lazy (for a long call chain)
12+
.filter { it.body.isNotBlank() && !it.isRead } // Use lambdas...
13+
.map(Message::sender) // ...or member references
14+
.distinct()
15+
.sorted()
16+
.toList() // Convert sequence back to a list to get a result
17+
println(senders) // [Adam, Ma]
18+
}
19+
20+
data class Message( // Create a data class
21+
val sender: String,
22+
val body: String,
23+
val isRead: Boolean = false, // Provide a default value for the argument
24+
)
25+
26+
val messages = listOf( // Create a list
27+
Message("Ma", "Hey! Where are you?"),
28+
Message("Adam", "Everything going according to plan today?"),
29+
Message("Ma", "Please reply. I've lost you!"),
30+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Tests
2+
// The following example works for JVM only
3+
import org.junit.Test
4+
import kotlin.test.*
5+
6+
class SampleTest {
7+
@Test
8+
fun `test sum`() { // Write test names with whitespaces in backticks
9+
val a = 1
10+
val b = 41
11+
assertEquals(42, sum(a, b), "Wrong result for sum($a, $b)")
12+
}
13+
14+
@Test
15+
fun `test computation`() {
16+
assertTrue("Computation failed") {
17+
setup() // Use lambda returning the test subject
18+
compute()
19+
}
20+
}
21+
}
22+
23+
// Sources
24+
fun sum(a: Int, b: Int) = a + b
25+
fun setup() {}
26+
fun compute() = true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
abstract class Person(val name: String) {
2+
abstract fun greet()
3+
}
4+
5+
interface FoodConsumer {
6+
fun eat()
7+
fun pay(amount: Int) = println("Delicious! Here's $amount bucks!")
8+
}
9+
10+
class RestaurantCustomer(name: String, val dish: String) : Person(name), FoodConsumer {
11+
fun order() = println("$dish, please!")
12+
override fun eat() = println("*Eats $dish*")
13+
override fun greet() = println("It's me, $name.")
14+
}
15+
16+
fun main() {
17+
val sam = RestaurantCustomer("Sam", "Mixed salad")
18+
sam.greet() // An implementation of an abstract function
19+
sam.order() // A member function
20+
sam.eat() // An implementation of an interface function
21+
sam.pay(10) // A default implementation in an interface
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fun main() {
2+
val name = "stranger" // Declare your first variable
3+
println("Hi, $name!") // ...and use it!
4+
print("Current count:")
5+
for (i in 0..10) { // Loop over a range from 0 to 10
6+
print(" $i")
7+
}
8+
}

blocks/main/why-kotlin/playground.css

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
.kotlin-code-examples-section {
2+
3+
.CodeMirror,
4+
.CodeMirror pre,
5+
.CodeMirror .CodeMirror-code,
6+
.CodeMirror .CodeMirror-code pre {
7+
font-family: 'JetBrains Mono', monospace;
8+
font-size: 16px;
9+
}
10+
11+
.CodeMirror pre.CodeMirror-line {
12+
font-size: 16px;
13+
line-height: 24px;
14+
}
15+
16+
.CodeMirror-scroll {
17+
height: auto !important;
18+
}
19+
20+
.CodeMirror-hint {
21+
height: 20px;
22+
max-width: 600px;
23+
}
24+
25+
.CodeMirror .CodeMirror-lines pre.CodeMirror-line, .CodeMirror .CodeMirror-lines pre.CodeMirror-line-like {
26+
font-variant-ligatures: none;
27+
}
28+
29+
.CodeMirror-gutters {
30+
background: none !important;
31+
border-right: none !important;
32+
}
33+
34+
.executable-fragment-wrapper {
35+
margin-bottom: 0;
36+
}
37+
38+
.executable-fragment.darcula,
39+
.sample[theme=darcula] {
40+
background: #27282C;
41+
border-bottom-right-radius: 8px;
42+
border-bottom-left-radius: 8px;
43+
border: 0 none transparent;
44+
}
45+
46+
.sample[theme=darcula] {
47+
padding: 20px 0 0 0;
48+
}
49+
50+
.cm-s-darcula.CodeMirror,
51+
.output-wrapper.darcula {
52+
background: transparent;
53+
}
54+
55+
.code-output {
56+
overflow-y: hidden;
57+
}
58+
59+
.output-wrapper.darcula {
60+
min-height: 120px;
61+
font-size: 16px;
62+
line-height: 24px;
63+
64+
border: 0 none transparent;
65+
border-top: 1px solid rgba(255, 255, 255, 0.2);
66+
}
67+
68+
.console-close {
69+
top: 5px;
70+
right: 5px;
71+
height: 16px;
72+
width: 16px;
73+
}
74+
75+
.compiler-info {
76+
display: none;
77+
}
78+
79+
.js-code-output-executor.darcula {
80+
border: 0 none transparent;
81+
}
82+
83+
.run-button {
84+
display: none;
85+
}
86+
}
87+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
@import "@jetbrains/kotlin-web-site-ui/out/components/breakpoints/media.pcss";
2+
@import './playground.css';
3+
4+
.whyKotlin {
5+
background: #19191C;
6+
padding: 96px;
7+
@media (--ktl-tm) {
8+
padding: 48px 0;
9+
}
10+
}
11+
12+
.sectionTitle {
13+
margin-bottom: 24px;
14+
}
15+
16+
.getStartedButton {
17+
margin-top: 24px;
18+
}
19+
20+
.navigationBar {
21+
display: flex;
22+
align-items: center;
23+
justify-content: space-between;
24+
height: 52px;
25+
padding: 0 12px;
26+
}
27+
28+
.tabList {
29+
@media (--ktl-tm) {
30+
display: none;
31+
}
32+
}
33+
34+
.tab {
35+
display: block;
36+
}
37+
38+
.codeExamples {
39+
background: #27282C;
40+
min-height: 492px;
41+
border-radius: 8px;
42+
}
43+
44+
.openInPlaygoundButton {
45+
@media (--ktl-tl) {
46+
display: none;
47+
}
48+
}
49+
50+
.mobileMenuButton {
51+
display: none;
52+
@media (--ktl-tl) {
53+
display: block;
54+
}
55+
}
56+

blocks/main/why-kotlin/why-kotlin.tsx

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import React, { FC, useState, useContext } from 'react';
2+
import cn from 'classnames';
3+
4+
import { useTextStyles, createTextCn } from '@rescui/typography';
5+
import { TabList, Tab } from '@rescui/tab-list';
6+
import { Button } from '@rescui/button';
7+
import { ThemeProvider } from '@rescui/ui-contexts';
8+
import { CodeIcon, PlayIcon } from '@rescui/icons';
9+
10+
import '@jetbrains/kotlin-web-site-ui/out/components/layout';
11+
12+
import { CodeBlock } from '../../../components/code-block/code-block';
13+
14+
import styles from './why-kotlin.module.css';
15+
import './playground.css';
16+
17+
import { CodeBlockContext } from '../../../components/code-block/code-block';
18+
19+
import simpleExample from './code-examples/simple.md';
20+
import asyncExample from './code-examples/asynchronous.md';
21+
import oopExample from './code-examples/object-oriented.md';
22+
import functionalExample from './code-examples/functional.md';
23+
import testsExample from './code-examples/ideal-for-tests.md';
24+
25+
interface Props {}
26+
27+
const ContentSwitcher = ({ index, children }) => {
28+
return children[index];
29+
};
30+
31+
export const WhyKotlin: FC<Props> = ({}) => {
32+
const [activeIndex, setActiveIndex] = useState(0);
33+
34+
const textCn = useTextStyles();
35+
const darkTextCn = createTextCn('dark');
36+
37+
const codeBlockInstance = useContext(CodeBlockContext);
38+
39+
const handleRunButton = () => {
40+
codeBlockInstance.execute();
41+
};
42+
43+
return (
44+
<ThemeProvider theme={'dark'}>
45+
<section className={styles.whyKotlin}>
46+
<div className={cn('ktl-layout', 'ktl-layout--center')}>
47+
<div className={cn(darkTextCn('rs-h1'), styles.sectionTitle)}>Why Kotlin</div>
48+
49+
<div className={styles.codeExamples}>
50+
<div className={styles.navigationBar}>
51+
<div className={styles.mobileMenuButton}>
52+
<Button mode={'clear'} size={'m'}>
53+
Mobile button
54+
</Button>
55+
</div>
56+
57+
<TabList
58+
value={activeIndex}
59+
onChange={(v) => setActiveIndex(v)}
60+
mode={'rock'}
61+
size={'m'}
62+
className={styles.tabList}
63+
>
64+
<Tab>Simple</Tab>
65+
<Tab>Asynchronous</Tab>
66+
<Tab>Object-oriented</Tab>
67+
<Tab>Functional</Tab>
68+
<Tab>Ideal for tests</Tab>
69+
</TabList>
70+
71+
<div>
72+
<Button
73+
mode={'clear'}
74+
size={'m'}
75+
icon={<CodeIcon />}
76+
className={styles.openInPlaygoundButton}
77+
>
78+
Open in Playground
79+
</Button>
80+
<Button mode={'clear'} size={'m'} icon={<PlayIcon />} onClick={handleRunButton}>
81+
Run
82+
</Button>
83+
</div>
84+
</div>
85+
86+
<div className="tab-content kotlin-code-examples-section">
87+
<ContentSwitcher index={activeIndex}>
88+
<div className={styles.tab} key={0}>
89+
<CodeBlock>{simpleExample}</CodeBlock>
90+
</div>
91+
<div className={styles.tab} key={1}>
92+
<CodeBlock>{asyncExample}</CodeBlock>
93+
</div>
94+
<div className={styles.tab} key={2}>
95+
<CodeBlock>{oopExample}</CodeBlock>
96+
</div>
97+
<div className={styles.tab} key={3}>
98+
<CodeBlock>{functionalExample}</CodeBlock>
99+
</div>
100+
<div className={styles.tab} key={4}>
101+
<CodeBlock>{testsExample}</CodeBlock>
102+
</div>
103+
</ContentSwitcher>
104+
</div>
105+
</div>
106+
107+
<Button mode={'outline'} size={'l'} className={styles.getStartedButton}>
108+
Get started
109+
</Button>
110+
</div>
111+
</section>
112+
</ThemeProvider>
113+
);
114+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.code {
2+
display: none;
3+
}

0 commit comments

Comments
 (0)